4 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(_WIN32)
7 #include <sys/sysmacros.h>
13 #include <QFileInfoList>
15 #include <QJsonObject>
51 if ((pProgram ==
nullptr) || (pInfo ==
nullptr))
56 pProgram->setTitle ( pInfo->
GetTitle() );
60 pProgram->setRepeat ( pInfo->
IsRepeat() );
72 pProgram->setStars ( pInfo->
GetStars() );
90 pProgram->setAirdate( year );
95 pProgram->setSeason ( pInfo->
GetSeason() );
103 pProgram->enableCast(
false);
118 pProgram->enableChannel(
false);
139 pRecording->setFileName ( pRecInfo.
GetPathname() );
140 pRecording->setFileSize ( pRecInfo.
GetFilesize() );
141 pRecording->setHostName ( pRecInfo.
GetHostname() );
151 pRecording->setEncoderId ( pRecInfo.
GetInputID() );
158 pProgram->enableRecording(
false);
161 if ( bIncArtwork && !pInfo->
GetInetRef().isEmpty() )
164 pProgram->enableArtwork(
false);
176 if (channel.
Load(nChanID))
195 pChannel->setChanId(channelInfo.
m_chanId);
196 pChannel->setChanNum(channelInfo.
m_chanNum);
197 pChannel->setCallSign(channelInfo.
m_callSign);
198 if (!channelInfo.
m_icon.isEmpty())
200 QString sIconURL = QString(
"/Guide/GetChannelIcon?FileName=%1")
201 .arg( channelInfo.
m_icon );
202 pChannel->setIconURL( sIconURL );
203 pChannel->setIcon( channelInfo.
m_icon );
205 pChannel->setChannelName(channelInfo.
m_name);
211 pChannel->setMplexId(channelInfo.
m_mplexId);
216 pChannel->setFineTune(channelInfo.
m_fineTune);
217 pChannel->setFrequencyId(channelInfo.
m_freqId);
219 pChannel->setSourceId(channelInfo.
m_sourceId);
222 pChannel->setXMLTVID(channelInfo.
m_xmltvId);
226 pChannel->setTimeOffset(channelInfo.
m_tmOffset);
231 for (
int x = 0; x < groupIds.size(); x++)
236 sGroupIds += QString::number(groupIds.at(x));
238 pChannel->setChannelGroups(sGroupIds);
242 for (
int x = 0; x < inputIds.size(); x++)
247 sInputIds += QString::number(inputIds.at(x));
249 pChannel->setInputs(sInputIds);
260 pGroup->setGroupId(pGroupItem.
m_grpId);
261 pGroup->setName(pGroupItem.
m_name);
262 pGroup->setPassword(
"");
272 if ((pRecRule ==
nullptr) || (pRule ==
nullptr))
278 pRecRule->setTitle ( pRule->
m_title );
281 pRecRule->setSeason ( pRule->
m_season );
282 pRecRule->setEpisode ( pRule->
m_episode );
284 #if QT_VERSION < QT_VERSION_CHECK(6,5,0)
285 pRecRule->setStartTime ( QDateTime(pRule->
m_startdate,
287 pRecRule->setEndTime ( QDateTime(pRule->
m_enddate,
290 static const QTimeZone utc(QTimeZone::UTC);
291 pRecRule->setStartTime ( QDateTime(pRule->
m_startdate,
293 pRecRule->setEndTime ( QDateTime(pRule->
m_enddate,
298 pRecRule->setInetref ( pRule->
m_inetref );
300 pRecRule->setCallSign ( pRule->
m_station );
301 pRecRule->setFindDay ( pRule->
m_findday );
306 pRecRule->setPreferredInput ( pRule->
m_prefInput );
312 pRecRule->setFilter ( pRule->
m_filter );
336 const QString &sInetref,
340 for (
auto i = map.cbegin(); i != map.cend(); ++i)
343 pArtInfo->setFileName(i.value().url);
347 pArtInfo->setStorageGroup(
"Fanart");
348 pArtInfo->setType(
"fanart");
349 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
352 QString(QUrl::toPercentEncoding(
353 QUrl(i.value().url).path()))));
356 pArtInfo->setStorageGroup(
"Banners");
357 pArtInfo->setType(
"banner");
358 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
361 QString(QUrl::toPercentEncoding(
362 QUrl(i.value().url).path()))));
366 pArtInfo->setStorageGroup(
"Coverart");
367 pArtInfo->setType(
"coverart");
368 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
371 QString(QUrl::toPercentEncoding(
372 QUrl(i.value().url).path()))));
384 query.
prepare(
"SELECT genre from videogenre "
385 "LEFT JOIN videometadatagenre ON videometadatagenre.idgenre = videogenre.intid "
386 "WHERE idvideo = :ID "
390 if (query.
exec() && query.
size() > 0)
395 QString genre = query.
value(0).toString();
396 pGenre->setName(genre);
407 pVideoMetadataInfo->setId(pMetadata->GetID());
408 pVideoMetadataInfo->setTitle(pMetadata->GetTitle());
409 pVideoMetadataInfo->setSubTitle(pMetadata->GetSubtitle());
410 pVideoMetadataInfo->setTagline(pMetadata->GetTagline());
411 pVideoMetadataInfo->setDirector(pMetadata->GetDirector());
412 pVideoMetadataInfo->setStudio(pMetadata->GetStudio());
413 pVideoMetadataInfo->setDescription(pMetadata->GetPlot());
414 pVideoMetadataInfo->setCertification(pMetadata->GetRating());
415 pVideoMetadataInfo->setInetref(pMetadata->GetInetRef());
416 pVideoMetadataInfo->setCollectionref(pMetadata->GetCollectionRef());
417 pVideoMetadataInfo->setHomePage(pMetadata->GetHomepage());
418 #if QT_VERSION < QT_VERSION_CHECK(6,5,0)
419 pVideoMetadataInfo->setReleaseDate(
420 QDateTime(pMetadata->GetReleaseDate(),
421 QTime(0,0),Qt::LocalTime).toUTC());
422 pVideoMetadataInfo->setAddDate(
423 QDateTime(pMetadata->GetInsertdate(),
424 QTime(0,0),Qt::LocalTime).toUTC());
426 static const QTimeZone localtime(QTimeZone::LocalTime);
427 pVideoMetadataInfo->setReleaseDate(
428 QDateTime(pMetadata->GetReleaseDate(),
429 QTime(0,0),localtime).toUTC());
430 pVideoMetadataInfo->setAddDate(
431 QDateTime(pMetadata->GetInsertdate(),
432 QTime(0,0),localtime).toUTC());
434 pVideoMetadataInfo->setUserRating(pMetadata->GetUserRating());
435 pVideoMetadataInfo->setChildID(pMetadata->GetChildID());
436 pVideoMetadataInfo->setLength(pMetadata->GetLength().count());
437 pVideoMetadataInfo->setPlayCount(pMetadata->GetPlayCount());
438 pVideoMetadataInfo->setSeason(pMetadata->GetSeason());
439 pVideoMetadataInfo->setEpisode(pMetadata->GetEpisode());
440 pVideoMetadataInfo->setParentalLevel(pMetadata->GetShowLevel());
441 pVideoMetadataInfo->setVisible(pMetadata->GetBrowse());
442 pVideoMetadataInfo->setWatched(pMetadata->GetWatched());
443 pVideoMetadataInfo->setProcessed(pMetadata->GetProcessed());
445 pMetadata->GetContentType()));
446 pVideoMetadataInfo->setFileName(pMetadata->GetFilename());
447 pVideoMetadataInfo->setHash(pMetadata->GetHash());
448 pVideoMetadataInfo->setHostName(pMetadata->GetHost());
449 pVideoMetadataInfo->setCoverart(pMetadata->GetCoverFile());
450 pVideoMetadataInfo->setFanart(pMetadata->GetFanart());
451 pVideoMetadataInfo->setBanner(pMetadata->GetBanner());
452 pVideoMetadataInfo->setScreenshot(pMetadata->GetScreenshot());
453 pVideoMetadataInfo->setTrailer(pMetadata->GetTrailer());
454 pVideoMetadataInfo->setCategory(pMetadata->GetCategoryID());
458 if (!pMetadata->GetFanart().isEmpty())
461 pVideoMetadataInfo->
Artwork()->AddNewArtworkInfo();
462 pArtInfo->setStorageGroup(
"Fanart");
463 pArtInfo->setType(
"fanart");
464 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
468 QUrl::toPercentEncoding(pMetadata->GetFanart()))));
470 if (!pMetadata->GetCoverFile().isEmpty())
473 pVideoMetadataInfo->
Artwork()->AddNewArtworkInfo();
474 pArtInfo->setStorageGroup(
"Coverart");
475 pArtInfo->setType(
"coverart");
476 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
480 QUrl::toPercentEncoding(pMetadata->GetCoverFile()))));
482 if (!pMetadata->GetBanner().isEmpty())
485 pVideoMetadataInfo->
Artwork()->AddNewArtworkInfo();
486 pArtInfo->setStorageGroup(
"Banners");
487 pArtInfo->setType(
"banner");
488 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
492 QUrl::toPercentEncoding(pMetadata->GetBanner()))));
494 if (!pMetadata->GetScreenshot().isEmpty())
497 pVideoMetadataInfo->
Artwork()->AddNewArtworkInfo();
498 pArtInfo->setStorageGroup(
"Screenshots");
499 pArtInfo->setType(
"screenshot");
500 pArtInfo->setURL(QString(
"/Content/GetImageFile?StorageGroup=%1"
504 QUrl::toPercentEncoding(pMetadata->GetScreenshot()))));
510 auto castList = pMetadata->GetCast();
513 QString actors = QObject::tr(
"Actors");
517 pCastMember->setTranslatedRole(actors);
518 pCastMember->setRole(
"ACTOR");
519 pCastMember->setName(ent.second);
531 pVideoMetadataInfo->setId(pMetadata->
ID());
532 pVideoMetadataInfo->setArtist(pMetadata->
Artist());
534 pVideoMetadataInfo->setAlbum(pMetadata->
Album());
535 pVideoMetadataInfo->setTitle(pMetadata->
Title());
536 pVideoMetadataInfo->setTrackNo(pMetadata->
Track());
537 pVideoMetadataInfo->setGenre(pMetadata->
Genre());
538 pVideoMetadataInfo->setYear(pMetadata->
Year());
539 pVideoMetadataInfo->setPlayCount(pMetadata->
PlayCount());
540 pVideoMetadataInfo->setLength(pMetadata->
Length().count());
541 pVideoMetadataInfo->setRating(pMetadata->
Rating());
542 pVideoMetadataInfo->setFileName(pMetadata->
Filename());
543 pVideoMetadataInfo->setHostName(pMetadata->
Hostname());
544 pVideoMetadataInfo->setLastPlayed(pMetadata->
LastPlay());
545 pVideoMetadataInfo->setCompilation(pMetadata->
Compilation());
556 input->setInputName(inputInfo.
m_name);
571 if (!pCastMemberList || !pInfo)
578 table =
"recordedcredits";
582 query.
prepare(QString(
"SELECT role, people.name, roles.name FROM %1"
584 " LEFT JOIN people ON"
585 " credits.person = people.person"
586 " LEFT JOIN roles ON"
587 " credits.roleid = roles.roleid"
588 " WHERE credits.chanid = :CHANID"
589 " AND credits.starttime = :STARTTIME"
590 " ORDER BY role, priority;").arg(table));
595 if (query.
exec() && query.
size() > 0)
597 QMap<QString, QString> translations;
598 translations[
"ACTOR"] = QObject::tr(
"Actors");
599 translations[
"DIRECTOR"] = QObject::tr(
"Director");
600 translations[
"PRODUCER"] = QObject::tr(
"Producer");
601 translations[
"EXECUTIVE_PRODUCER"] = QObject::tr(
"Executive Producer");
602 translations[
"WRITER"] = QObject::tr(
"Writer");
603 translations[
"GUEST_STAR"] = QObject::tr(
"Guest Star");
604 translations[
"HOST"] = QObject::tr(
"Host");
605 translations[
"ADAPTER"] = QObject::tr(
"Adapter");
606 translations[
"PRESENTER"] = QObject::tr(
"Presenter");
607 translations[
"COMMENTATOR"] = QObject::tr(
"Commentator");
608 translations[
"GUEST"] = QObject::tr(
"Guest");
614 QString role = query.
value(0).toString();
615 pCastMember->setTranslatedRole(translations.value(role.toUpper()));
616 pCastMember->setRole(role);
632 pCastMember->setName(QString::fromUtf8(query.
value(1)
633 .toByteArray().constData()));
634 pCastMember->setCharacterName(QString::fromUtf8(query.
value(2)
635 .toByteArray().constData()));
645 frm_dir_map_t::const_iterator it;
652 it = markMap.cbegin();
653 if (it != markMap.cend())
656 pCutting->setMark(*it);
657 pCutting->setOffset(it.key());
663 for (it = markMap.cbegin(); it != markMap.cend(); ++it)
669 pCutting->setMark(*it);
670 pCutting->setOffset(it.key());
672 else if (marktype == 1)
678 pCutting->setMark(*it);
679 pCutting->setOffset(offset);
682 else if (marktype == 2)
688 pCutting->setMark(*it);
689 pCutting->setOffset(offset);
699 frm_dir_map_t::const_iterator it;
706 it = markMap.cbegin();
707 if (it != markMap.cend())
710 pCutting->setMark(*it);
711 pCutting->setOffset(it.key());
717 for (it = markMap.cbegin(); it != markMap.cend(); ++it)
723 pCutting->setMark(*it);
724 pCutting->setOffset(it.key());
726 else if (marktype == 1)
732 pCutting->setMark(*it);
733 pCutting->setOffset(offset);
736 else if (marktype == 2)
742 pCutting->setMark(*it);
743 pCutting->setOffset(offset);
757 frm_pos_map_t::const_iterator it;
763 for (it = markMap.cbegin(); it != markMap.cend(); ++it)
766 pCutting->setMark(it.key());
767 pCutting->setOffset(it.value());
776 for (
auto * elink : std::as_const(
gTVList))
778 if (elink !=
nullptr)
781 auto *pEncoder =
new V2Encoder( parent );
782 list.append( QVariant::fromValue<QObject *>( pEncoder ));
784 pEncoder->setId ( elink->GetInputID() );
785 pEncoder->setState ( elink->GetState() );
786 pEncoder->setLocal ( elink->IsLocal() );
787 pEncoder->setConnected ( elink->IsConnected() );
788 pEncoder->setSleepStatus ( elink->GetSleepStatus() );
790 if (pEncoder->GetLocal())
793 pEncoder->setHostName( elink->GetHostName() );
795 for (
const auto & inputInfo : std::as_const(inputInfoList))
797 if (inputInfo.m_inputId ==
static_cast<uint>(elink->GetInputID()))
799 V2Input *input = pEncoder->AddNewInput();
804 bool progFound =
false;
806 switch ( pEncoder->GetState() )
828 pProgram->setProperty(
"isNull",QVariant(
true));
842 const QString &RecGroup )
862 for (
auto it = tmpList.begin(); it < tmpList.end(); ++it)
864 if ((nRecStatus == -999
865 && (*it)->GetRecordingStatus() >= 0)
866 || (nRecStatus != 0 && nRecStatus != -999
867 && (*it)->GetRecordingStatus() != nRecStatus))
874 if (!RecGroup.isEmpty())
876 if ( (*it)-> GetRecordingGroup() != RecGroup )
905 if (Sort.startsWith(
"channum", Qt::CaseInsensitive))
907 else if (Sort.startsWith(
"title", Qt::CaseInsensitive))
909 else if (Sort.startsWith(
"length", Qt::CaseInsensitive))
911 else if (Sort.startsWith(
"status", Qt::CaseInsensitive))
913 if (Sort.endsWith(
"desc", Qt::CaseInsensitive))
916 static QRegularExpression regex(
"[_-]");
927 return First->
GetChanNum().replace(regex,
".").toDouble()
928 < Second->GetChanNum().replace(regex,
".").toDouble();
930 return First->
GetChanNum().replace(regex,
".").toDouble()
931 > Second->GetChanNum().replace(regex,
".").toDouble();
933 return QString::compare(First->
GetSortTitle(), Second->GetSortTitle(), Qt::CaseInsensitive) < 0 ;
935 return QString::compare(First->
GetSortTitle(), Second->GetSortTitle(), Qt::CaseInsensitive) > 0 ;
939 qint64 time2 = Second->GetScheduledStartTime().msecsTo( Second->GetScheduledEndTime());
940 return time1 < time2 ;
945 qint64 time2 = Second->GetScheduledStartTime().msecsTo( Second->GetScheduledEndTime());
946 return time1 > time2 ;
951 Qt::CaseInsensitive) < 0 ;
955 Qt::CaseInsensitive) > 0 ;
962 std::stable_sort(recordingList.
begin(), recordingList.
end(), comp);
968 nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (
int)recordingList.
size() ) : 0;
969 nCount = (nCount > 0) ? std::min( nCount, (
int)recordingList.
size() ) : recordingList.
size();
970 int nEndIndex = std::min((nStartIndex + nCount), (
int)recordingList.
size() );
972 for(
int n = nStartIndex; n < nEndIndex; n++)
975 auto *pProgram =
new V2Program( parent );
976 list.append( QVariant::fromValue<QObject *>( pProgram ));
980 return recordingList.
size();
985 QMap<QString, Frontend*> frontends;
991 for (
auto * fe : std::as_const(frontends))
994 list.append( QVariant::fromValue<QObject *>( pFrontend ));
995 pFrontend->setName(fe->m_name);
996 pFrontend->setIP(fe->m_ip.toString());
999 pFrontend->setPort(port);
1000 pFrontend->setOnLine(fe->m_connectionCount > 0);
1010 query.
prepare(
"INSERT INTO recgroups SET recgroup = :NAME, "
1011 "displayname = :DISPLAYNAME");
1013 query.
bindValue(
":DISPLAYNAME", groupName);
1019 LOG(VB_GENERAL, LOG_ERR, QString(
"Could not create recording group (%1). "
1020 "Does it already exist?").arg(groupName));
1030 QJsonArray members = cast[
"CastMembers"].toArray();
1031 for (
const auto & m : std::as_const(members))
1033 QJsonObject actor = m.toObject();
1034 QString name = actor.value(
"Name").toString(
"");
1035 QString character = actor.value(
"CharacterName").toString(
"");
1036 QString role = actor.value(
"Role").toString(
"");
1038 credits->emplace_back(role, name, priority++, character);
1049 uint minor_max = 15;
1050 QString card = QString();
1053 QDir dev(
"/dev/v4l",
"video*", QDir::Name, QDir::System);
1055 card, driver,
false, pList, cardType);
1058 dev.setPath(
"/dev");
1060 card, driver,
false, pList, cardType);
1063 dev.setPath(
"/dev/dtv");
1065 card, driver,
false, pList, cardType);
1068 dev.setPath(
"/dev");
1069 dev.setNameFilters(QStringList(
"dtv*"));
1071 card, driver,
false, pList, cardType);
1078 const QString& card,
const QRegularExpression& driver,
1080 const QString & cardType)
1083 QMap<uint, uint> minorlist;
1084 QFileInfoList entries = dir.entryInfoList();
1085 for (
const auto & fi : std::as_const(entries))
1088 QString filepath = fi.absoluteFilePath();
1089 int err =
lstat(filepath.toLocal8Bit().constData(), &st);
1093 LOG(VB_GENERAL, LOG_ERR,
1094 QString(
"Could not stat file: %1").arg(filepath));
1099 if (!S_ISCHR(st.st_mode))
1104 if (minor_min > minor_num || minor_max < minor_num)
1108 if (!allow_duplicates && minorlist[minor_num])
1112 QByteArray
tmp = filepath.toLatin1();
1113 int videofd = open(
tmp.constData(), O_RDWR);
1117 QString driver_name;
1120 auto match = driver.match(driver_name);
1121 if ((!driver.pattern().isEmpty() || match.hasMatch()) &&
1122 (card.isEmpty() || (card_name == card)))
1125 pDev->setCardType (cardType);
1126 pDev->setVideoDevice (filepath);
1127 pDev->setFrontendName(card_name);
1130 pDev->setInputNames(inputs);
1132 pDev->setAudioDevices(inputs);
1133 if (cardType ==
"HDPVR")
1134 pDev->setChannelTimeout ( 15000 );
1141 minorlist[minor_num] = 1;
1153 for (
auto &
info : list)
1155 auto* pDev = pList->AddCaptureDevice();
1156 pDev->setCardType (cardType);
1157 QString guid =
info.GetGUIDString();
1158 pDev->setVideoDevice (guid);
1160 pDev->setFirewireModel(model);
1161 pDev->setDescription(
info.m_product_name);
1162 pDev->setSignalTimeout ( 2000 );
1163 pDev->setChannelTimeout ( 9000 );
1165 #endif // CONFIG_FIREWIRE