4 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(_WIN32)
7 #include <sys/sysmacros.h>
13 #include <QFileInfoList>
15 #include <QJsonObject>
50 if ((pProgram ==
nullptr) || (pInfo ==
nullptr))
55 pProgram->setTitle ( pInfo->
GetTitle() );
59 pProgram->setRepeat ( pInfo->
IsRepeat() );
71 pProgram->setStars ( pInfo->
GetStars() );
89 pProgram->setAirdate( year );
94 pProgram->setSeason ( pInfo->
GetSeason() );
102 pProgram->enableCast(
false);
117 pProgram->enableChannel(
false);
138 pRecording->setFileName ( pRecInfo.
GetPathname() );
139 pRecording->setFileSize ( pRecInfo.
GetFilesize() );
140 pRecording->setHostName ( pRecInfo.
GetHostname() );
150 pRecording->setEncoderId ( pRecInfo.
GetInputID() );
157 pProgram->enableRecording(
false);
160 if ( bIncArtwork && !pInfo->
GetInetRef().isEmpty() )
163 pProgram->enableArtwork(
false);
175 if (channel.
Load(nChanID))
194 pChannel->setChanId(channelInfo.
m_chanId);
195 pChannel->setChanNum(channelInfo.
m_chanNum);
196 pChannel->setCallSign(channelInfo.
m_callSign);
197 if (!channelInfo.
m_icon.isEmpty())
199 QString sIconURL = QString(
"/Guide/GetChannelIcon?FileName=%1")
200 .arg( channelInfo.
m_icon );
201 pChannel->setIconURL( sIconURL );
202 pChannel->setIcon( channelInfo.
m_icon );
204 pChannel->setChannelName(channelInfo.
m_name);
210 pChannel->setMplexId(channelInfo.
m_mplexId);
215 pChannel->setFineTune(channelInfo.
m_fineTune);
216 pChannel->setFrequencyId(channelInfo.
m_freqId);
218 pChannel->setSourceId(channelInfo.
m_sourceId);
221 pChannel->setXMLTVID(channelInfo.
m_xmltvId);
225 pChannel->setTimeOffset(channelInfo.
m_tmOffset);
230 for (
int x = 0; x < groupIds.size(); x++)
235 sGroupIds += QString::number(groupIds.at(x));
237 pChannel->setChannelGroups(sGroupIds);
241 for (
int x = 0; x < inputIds.size(); x++)
246 sInputIds += QString::number(inputIds.at(x));
248 pChannel->setInputs(sInputIds);
259 pGroup->setGroupId(pGroupItem.
m_grpId);
260 pGroup->setName(pGroupItem.
m_name);
261 pGroup->setPassword(
"");
271 if ((pRecRule ==
nullptr) || (pRule ==
nullptr))
277 pRecRule->setTitle ( pRule->
m_title );
280 pRecRule->setSeason ( pRule->
m_season );
281 pRecRule->setEpisode ( pRule->
m_episode );
283 #if QT_VERSION < QT_VERSION_CHECK(6,5,0)
284 pRecRule->setStartTime ( QDateTime(pRule->
m_startdate,
286 pRecRule->setEndTime ( QDateTime(pRule->
m_enddate,
289 static const QTimeZone utc(QTimeZone::UTC);
290 pRecRule->setStartTime ( QDateTime(pRule->
m_startdate,
292 pRecRule->setEndTime ( QDateTime(pRule->
m_enddate,
297 pRecRule->setInetref ( pRule->
m_inetref );
299 pRecRule->setCallSign ( pRule->
m_station );
300 pRecRule->setFindDay ( pRule->
m_findday );
305 pRecRule->setPreferredInput ( pRule->
m_prefInput );
311 pRecRule->setFilter ( pRule->
m_filter );
335 const QString &sInetref,
339 for (
auto i = map.cbegin(); i != map.cend(); ++i)
342 pArtInfo->setFileName(i.value().url);
346 pArtInfo->setStorageGroup(
"Fanart");
347 pArtInfo->setType(
"fanart");
348 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
351 QString(QUrl::toPercentEncoding(
352 QUrl(i.value().url).path()))));
355 pArtInfo->setStorageGroup(
"Banners");
356 pArtInfo->setType(
"banner");
357 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
360 QString(QUrl::toPercentEncoding(
361 QUrl(i.value().url).path()))));
365 pArtInfo->setStorageGroup(
"Coverart");
366 pArtInfo->setType(
"coverart");
367 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
370 QString(QUrl::toPercentEncoding(
371 QUrl(i.value().url).path()))));
383 query.
prepare(
"SELECT genre from videogenre "
384 "LEFT JOIN videometadatagenre ON videometadatagenre.idgenre = videogenre.intid "
385 "WHERE idvideo = :ID "
389 if (query.
exec() && query.
size() > 0)
394 QString genre = query.
value(0).toString();
395 pGenre->setName(genre);
406 pVideoMetadataInfo->setId(pMetadata->GetID());
407 pVideoMetadataInfo->setTitle(pMetadata->GetTitle());
408 pVideoMetadataInfo->setSubTitle(pMetadata->GetSubtitle());
409 pVideoMetadataInfo->setTagline(pMetadata->GetTagline());
410 pVideoMetadataInfo->setDirector(pMetadata->GetDirector());
411 pVideoMetadataInfo->setStudio(pMetadata->GetStudio());
412 pVideoMetadataInfo->setDescription(pMetadata->GetPlot());
413 pVideoMetadataInfo->setCertification(pMetadata->GetRating());
414 pVideoMetadataInfo->setInetref(pMetadata->GetInetRef());
415 pVideoMetadataInfo->setCollectionref(pMetadata->GetCollectionRef());
416 pVideoMetadataInfo->setHomePage(pMetadata->GetHomepage());
417 #if QT_VERSION < QT_VERSION_CHECK(6,5,0)
418 pVideoMetadataInfo->setReleaseDate(
419 QDateTime(pMetadata->GetReleaseDate(),
420 QTime(0,0),Qt::LocalTime).toUTC());
421 pVideoMetadataInfo->setAddDate(
422 QDateTime(pMetadata->GetInsertdate(),
423 QTime(0,0),Qt::LocalTime).toUTC());
425 static const QTimeZone localtime(QTimeZone::LocalTime);
426 pVideoMetadataInfo->setReleaseDate(
427 QDateTime(pMetadata->GetReleaseDate(),
428 QTime(0,0),localtime).toUTC());
429 pVideoMetadataInfo->setAddDate(
430 QDateTime(pMetadata->GetInsertdate(),
431 QTime(0,0),localtime).toUTC());
433 pVideoMetadataInfo->setUserRating(pMetadata->GetUserRating());
434 pVideoMetadataInfo->setChildID(pMetadata->GetChildID());
435 pVideoMetadataInfo->setLength(pMetadata->GetLength().count());
436 pVideoMetadataInfo->setPlayCount(pMetadata->GetPlayCount());
437 pVideoMetadataInfo->setSeason(pMetadata->GetSeason());
438 pVideoMetadataInfo->setEpisode(pMetadata->GetEpisode());
439 pVideoMetadataInfo->setParentalLevel(pMetadata->GetShowLevel());
440 pVideoMetadataInfo->setVisible(pMetadata->GetBrowse());
441 pVideoMetadataInfo->setWatched(pMetadata->GetWatched());
442 pVideoMetadataInfo->setProcessed(pMetadata->GetProcessed());
444 pMetadata->GetContentType()));
445 pVideoMetadataInfo->setFileName(pMetadata->GetFilename());
446 pVideoMetadataInfo->setHash(pMetadata->GetHash());
447 pVideoMetadataInfo->setHostName(pMetadata->GetHost());
448 pVideoMetadataInfo->setCoverart(pMetadata->GetCoverFile());
449 pVideoMetadataInfo->setFanart(pMetadata->GetFanart());
450 pVideoMetadataInfo->setBanner(pMetadata->GetBanner());
451 pVideoMetadataInfo->setScreenshot(pMetadata->GetScreenshot());
452 pVideoMetadataInfo->setTrailer(pMetadata->GetTrailer());
456 if (!pMetadata->GetFanart().isEmpty())
459 pVideoMetadataInfo->
Artwork()->AddNewArtworkInfo();
460 pArtInfo->setStorageGroup(
"Fanart");
461 pArtInfo->setType(
"fanart");
462 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
466 QUrl::toPercentEncoding(pMetadata->GetFanart()))));
468 if (!pMetadata->GetCoverFile().isEmpty())
471 pVideoMetadataInfo->
Artwork()->AddNewArtworkInfo();
472 pArtInfo->setStorageGroup(
"Coverart");
473 pArtInfo->setType(
"coverart");
474 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
478 QUrl::toPercentEncoding(pMetadata->GetCoverFile()))));
480 if (!pMetadata->GetBanner().isEmpty())
483 pVideoMetadataInfo->
Artwork()->AddNewArtworkInfo();
484 pArtInfo->setStorageGroup(
"Banners");
485 pArtInfo->setType(
"banner");
486 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
490 QUrl::toPercentEncoding(pMetadata->GetBanner()))));
492 if (!pMetadata->GetScreenshot().isEmpty())
495 pVideoMetadataInfo->
Artwork()->AddNewArtworkInfo();
496 pArtInfo->setStorageGroup(
"Screenshots");
497 pArtInfo->setType(
"screenshot");
498 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
502 QUrl::toPercentEncoding(pMetadata->GetScreenshot()))));
508 auto castList = pMetadata->GetCast();
511 QString actors = QObject::tr(
"Actors");
515 pCastMember->setTranslatedRole(actors);
516 pCastMember->setRole(
"ACTOR");
517 pCastMember->setName(ent.second);
529 pVideoMetadataInfo->setId(pMetadata->
ID());
530 pVideoMetadataInfo->setArtist(pMetadata->
Artist());
532 pVideoMetadataInfo->setAlbum(pMetadata->
Album());
533 pVideoMetadataInfo->setTitle(pMetadata->
Title());
534 pVideoMetadataInfo->setTrackNo(pMetadata->
Track());
535 pVideoMetadataInfo->setGenre(pMetadata->
Genre());
536 pVideoMetadataInfo->setYear(pMetadata->
Year());
537 pVideoMetadataInfo->setPlayCount(pMetadata->
PlayCount());
538 pVideoMetadataInfo->setLength(pMetadata->
Length().count());
539 pVideoMetadataInfo->setRating(pMetadata->
Rating());
540 pVideoMetadataInfo->setFileName(pMetadata->
Filename());
541 pVideoMetadataInfo->setHostName(pMetadata->
Hostname());
542 pVideoMetadataInfo->setLastPlayed(pMetadata->
LastPlay());
543 pVideoMetadataInfo->setCompilation(pMetadata->
Compilation());
554 input->setInputName(inputInfo.
m_name);
569 if (!pCastMemberList || !pInfo)
576 table =
"recordedcredits";
580 query.
prepare(QString(
"SELECT role, people.name, roles.name FROM %1"
582 " LEFT JOIN people ON"
583 " credits.person = people.person"
584 " LEFT JOIN roles ON"
585 " credits.roleid = roles.roleid"
586 " WHERE credits.chanid = :CHANID"
587 " AND credits.starttime = :STARTTIME"
588 " ORDER BY role, priority;").arg(table));
593 if (query.
exec() && query.
size() > 0)
595 QMap<QString, QString> translations;
596 translations[
"ACTOR"] = QObject::tr(
"Actors");
597 translations[
"DIRECTOR"] = QObject::tr(
"Director");
598 translations[
"PRODUCER"] = QObject::tr(
"Producer");
599 translations[
"EXECUTIVE_PRODUCER"] = QObject::tr(
"Executive Producer");
600 translations[
"WRITER"] = QObject::tr(
"Writer");
601 translations[
"GUEST_STAR"] = QObject::tr(
"Guest Star");
602 translations[
"HOST"] = QObject::tr(
"Host");
603 translations[
"ADAPTER"] = QObject::tr(
"Adapter");
604 translations[
"PRESENTER"] = QObject::tr(
"Presenter");
605 translations[
"COMMENTATOR"] = QObject::tr(
"Commentator");
606 translations[
"GUEST"] = QObject::tr(
"Guest");
612 QString role = query.
value(0).toString();
613 pCastMember->setTranslatedRole(translations.value(role.toUpper()));
614 pCastMember->setRole(role);
630 pCastMember->setName(QString::fromUtf8(query.
value(1)
631 .toByteArray().constData()));
632 pCastMember->setCharacterName(QString::fromUtf8(query.
value(2)
633 .toByteArray().constData()));
643 frm_dir_map_t::const_iterator it;
650 it = markMap.cbegin();
651 if (it != markMap.cend())
654 pCutting->setMark(*it);
655 pCutting->setOffset(it.key());
661 for (it = markMap.cbegin(); it != markMap.cend(); ++it)
667 pCutting->setMark(*it);
668 pCutting->setOffset(it.key());
670 else if (marktype == 1)
676 pCutting->setMark(*it);
677 pCutting->setOffset(offset);
680 else if (marktype == 2)
686 pCutting->setMark(*it);
687 pCutting->setOffset(offset);
697 frm_dir_map_t::const_iterator it;
704 it = markMap.cbegin();
705 if (it != markMap.cend())
708 pCutting->setMark(*it);
709 pCutting->setOffset(it.key());
715 for (it = markMap.cbegin(); it != markMap.cend(); ++it)
721 pCutting->setMark(*it);
722 pCutting->setOffset(it.key());
724 else if (marktype == 1)
730 pCutting->setMark(*it);
731 pCutting->setOffset(offset);
734 else if (marktype == 2)
740 pCutting->setMark(*it);
741 pCutting->setOffset(offset);
755 frm_pos_map_t::const_iterator it;
761 for (it = markMap.cbegin(); it != markMap.cend(); ++it)
764 pCutting->setMark(it.key());
765 pCutting->setOffset(it.value());
774 for (
auto * elink : std::as_const(
gTVList))
776 if (elink !=
nullptr)
779 auto *pEncoder =
new V2Encoder( parent );
780 list.append( QVariant::fromValue<QObject *>( pEncoder ));
782 pEncoder->setId ( elink->GetInputID() );
783 pEncoder->setState ( elink->GetState() );
784 pEncoder->setLocal ( elink->IsLocal() );
785 pEncoder->setConnected ( elink->IsConnected() );
786 pEncoder->setSleepStatus ( elink->GetSleepStatus() );
788 if (pEncoder->GetLocal())
791 pEncoder->setHostName( elink->GetHostName() );
793 for (
const auto & inputInfo : std::as_const(inputInfoList))
795 if (inputInfo.m_inputId ==
static_cast<uint>(elink->GetInputID()))
797 V2Input *input = pEncoder->AddNewInput();
802 bool progFound =
false;
804 switch ( pEncoder->GetState() )
826 pProgram->setProperty(
"isNull",QVariant(
true));
839 const QString &Sort )
859 for (
auto it = tmpList.begin(); it < tmpList.end(); ++it)
861 if ((nRecStatus == -999
862 && (*it)->GetRecordingStatus() >= 0)
863 || (nRecStatus != 0 && nRecStatus != -999
864 && (*it)->GetRecordingStatus() != nRecStatus))
892 if (Sort.startsWith(
"channum", Qt::CaseInsensitive))
894 else if (Sort.startsWith(
"title", Qt::CaseInsensitive))
896 if (Sort.endsWith(
"desc", Qt::CaseInsensitive))
899 static QRegularExpression regex(
"[_-]");
910 return First->
GetChanNum().replace(regex,
".").toDouble()
911 < Second->GetChanNum().replace(regex,
".").toDouble();
913 return First->
GetChanNum().replace(regex,
".").toDouble()
914 > Second->GetChanNum().replace(regex,
".").toDouble();
916 return QString::compare(First->
GetTitle(), Second->GetTitle(), Qt::CaseInsensitive) < 0 ;
918 return QString::compare(First->
GetTitle(), Second->GetTitle(), Qt::CaseInsensitive) > 0 ;
925 std::stable_sort(recordingList.
begin(), recordingList.
end(), comp);
931 nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (
int)recordingList.
size() ) : 0;
932 nCount = (nCount > 0) ? std::min( nCount, (
int)recordingList.
size() ) : recordingList.
size();
933 int nEndIndex = std::min((nStartIndex + nCount), (
int)recordingList.
size() );
935 for(
int n = nStartIndex; n < nEndIndex; n++)
938 auto *pProgram =
new V2Program( parent );
939 list.append( QVariant::fromValue<QObject *>( pProgram ));
943 return recordingList.
size();
948 QMap<QString, Frontend*> frontends;
954 for (
auto * fe : std::as_const(frontends))
957 list.append( QVariant::fromValue<QObject *>( pFrontend ));
958 pFrontend->setName(fe->m_name);
959 pFrontend->setIP(fe->m_ip.toString());
962 pFrontend->setPort(port);
963 pFrontend->setOnLine(fe->m_connectionCount > 0);
973 query.
prepare(
"INSERT INTO recgroups SET recgroup = :NAME, "
974 "displayname = :DISPLAYNAME");
976 query.
bindValue(
":DISPLAYNAME", groupName);
982 LOG(VB_GENERAL, LOG_ERR, QString(
"Could not create recording group (%1). "
983 "Does it already exist?").arg(groupName));
993 QJsonArray members = cast[
"CastMembers"].toArray();
994 for (
const auto & m : std::as_const(members))
996 QJsonObject actor = m.toObject();
997 QString name = actor.value(
"Name").toString(
"");
998 QString character = actor.value(
"CharacterName").toString(
"");
999 QString role = actor.value(
"Role").toString(
"");
1001 credits->emplace_back(role, name, priority++, character);
1012 uint minor_max = 15;
1013 QString card = QString();
1016 QDir dev(
"/dev/v4l",
"video*", QDir::Name, QDir::System);
1018 card, driver,
false, pList, cardType);
1021 dev.setPath(
"/dev");
1023 card, driver,
false, pList, cardType);
1026 dev.setPath(
"/dev/dtv");
1028 card, driver,
false, pList, cardType);
1031 dev.setPath(
"/dev");
1032 dev.setNameFilters(QStringList(
"dtv*"));
1034 card, driver,
false, pList, cardType);
1041 const QString& card,
const QRegularExpression& driver,
1043 const QString & cardType)
1046 QMap<uint, uint> minorlist;
1047 QFileInfoList entries = dir.entryInfoList();
1048 for (
const auto & fi : std::as_const(entries))
1051 QString filepath = fi.absoluteFilePath();
1052 int err =
lstat(filepath.toLocal8Bit().constData(), &st);
1056 LOG(VB_GENERAL, LOG_ERR,
1057 QString(
"Could not stat file: %1").arg(filepath));
1062 if (!S_ISCHR(st.st_mode))
1067 if (minor_min > minor_num || minor_max < minor_num)
1071 if (!allow_duplicates && minorlist[minor_num])
1075 QByteArray
tmp = filepath.toLatin1();
1076 int videofd = open(
tmp.constData(), O_RDWR);
1080 QString driver_name;
1083 auto match = driver.match(driver_name);
1084 if ((!driver.pattern().isEmpty() || match.hasMatch()) &&
1085 (card.isEmpty() || (card_name == card)))
1088 pDev->setCardType (cardType);
1089 pDev->setVideoDevice (filepath);
1090 pDev->setFrontendName(card_name);
1093 pDev->setInputNames(inputs);
1095 pDev->setAudioDevices(inputs);
1096 if (cardType ==
"HDPVR")
1097 pDev->setChannelTimeout ( 15000 );
1104 minorlist[minor_num] = 1;
1114 #ifdef USING_FIREWIRE
1116 for (
auto &
info : list)
1118 auto* pDev = pList->AddCaptureDevice();
1119 pDev->setCardType (cardType);
1120 QString guid =
info.GetGUIDString();
1121 pDev->setVideoDevice (guid);
1123 pDev->setFirewireModel(model);
1124 pDev->setDescription(
info.m_product_name);
1125 pDev->setSignalTimeout ( 2000 );
1126 pDev->setChannelTimeout ( 9000 );
1128 #endif // USING_FIREWIRE