34 #include "libmythbase/mythversion.h"
67 qRegisterMetaType<V2ProgramGuide*>(
"V2ProgramGuide");
68 qRegisterMetaType<V2ProgramList*>(
"V2ProgramList");
69 qRegisterMetaType<V2Program*>(
"V2Program");
70 qRegisterMetaType<V2ChannelGroupList*>(
"V2ChannelGroupList");
71 qRegisterMetaType<V2ChannelGroup*>(
"V2ChannelGroup");
72 qRegisterMetaType<V2ChannelInfo*>(
"V2ChannelInfo");
73 qRegisterMetaType<V2RecordingInfo*>(
"V2RecordingInfo");
74 qRegisterMetaType<V2ArtworkInfoList*>(
"V2ArtworkInfoList");
75 qRegisterMetaType<V2ArtworkInfo*>(
"V2ArtworkInfo");
76 qRegisterMetaType<V2CastMemberList*>(
"V2CastMemberList");
77 qRegisterMetaType<V2CastMember*>(
"V2CastMember");
85 const QDateTime &rawEndTime,
92 if (!rawStartTime.isValid())
93 throw QString(
"StartTime is invalid" );
95 if (!rawEndTime.isValid())
96 throw QString(
"EndTime is invalid" );
98 QDateTime dtStartTime = rawStartTime.toUTC();
99 QDateTime dtEndTime = rawEndTime.toUTC();
101 if (dtEndTime < dtStartTime)
102 throw QString(
"EndTime is before StartTime");
104 if (nStartIndex <= 0)
114 uint nTotalAvailable = 0;
130 QString sWhere =
"program.chanid = :CHANID "
131 "AND program.endtime >= :STARTDATE "
132 "AND program.starttime < :ENDDATE "
133 "AND program.starttime >= :STARTDATELIMIT "
134 "AND program.manualid = 0";
137 QString sGroupBy =
"program.starttime, channel.channum,"
138 "channel.callsign, program.title";
141 QString sOrderBy =
"program.starttime";
143 bindings[
":STARTDATE" ] = dtStartTime;
144 bindings[
":STARTDATELIMIT"] = dtStartTime.addDays(-1);
145 bindings[
":ENDDATE" ] = dtEndTime;
163 ChannelInfoList::iterator chan_it;
164 for (chan_it = chanList.begin(); chan_it != chanList.end(); ++chan_it)
172 bindings[
":CHANID"] = (*chan_it).m_chanId;
178 for( progIt = progList.
begin(); progIt != progList.
end(); ++progIt)
187 pGuide->setStartTime ( dtStartTime );
188 pGuide->setEndTime ( dtEndTime );
189 pGuide->setDetails ( bDetails );
191 pGuide->setStartIndex ( nStartIndex );
192 pGuide->setCount ( chanList.size() );
193 pGuide->setTotalAvailable( nTotalAvailable );
196 pGuide->setVersion ( MYTH_BINARY_VERSION );
197 pGuide->setProtoVer ( MYTH_PROTO_VERSION );
208 const QDateTime& rawStartTime,
209 const QDateTime& rawEndTime,
211 const QString& sTitleFilter,
212 const QString& sCategoryFilter,
213 const QString& sPersonFilter,
214 const QString& sKeywordFilter,
217 const QString &sSort,
221 if (!rawStartTime.isNull() && !rawStartTime.isValid())
222 throw QString(
"StartTime is invalid" );
224 if (!rawEndTime.isNull() && !rawEndTime.isValid())
225 throw QString(
"EndTime is invalid" );
227 QDateTime dtStartTime = rawStartTime;
228 const QDateTime& dtEndTime = rawEndTime;
230 if (!rawEndTime.isNull() && dtEndTime < dtStartTime)
231 throw QString(
"EndTime is before StartTime");
246 if (!sPersonFilter.isEmpty())
248 sSQL =
", people, credits "
249 "WHERE people.name LIKE :PersonFilter "
250 "AND credits.person = people.person "
251 "AND program.chanid = credits.chanid "
252 "AND program.starttime = credits.starttime AND ";
253 bindings[
":PersonFilter"] = QString(
"%%1%").arg(sPersonFilter);
260 sSQL =
"LEFT JOIN oldprogram ON oldprogram.oldtitle = program.title "
262 +
"oldprogram.oldtitle IS NULL AND ";
265 sSQL +=
"deleted IS NULL AND ";
268 sSQL +=
"visible > 0 AND ";
270 sSQL +=
"program.manualid = 0 ";
277 sSQL +=
"AND program.chanid = :ChanId ";
278 bindings[
":ChanId"] = nChanId;
281 if (dtStartTime.isNull())
282 dtStartTime = QDateTime::currentDateTimeUtc();
284 sSQL +=
" AND program.endtime >= :StartDate ";
285 bindings[
":StartDate"] = dtStartTime;
287 if (!dtEndTime.isNull())
289 sSQL +=
"AND program.starttime <= :EndDate ";
290 bindings[
":EndDate"] = dtEndTime;
293 if (!sTitleFilter.isEmpty())
295 sSQL +=
"AND program.title LIKE :Title ";
296 bindings[
":Title"] = QString(
"%%1%").arg(sTitleFilter);
299 if (!sCategoryFilter.isEmpty())
301 sSQL +=
"AND program.category LIKE :Category ";
302 bindings[
":Category"] = sCategoryFilter;
305 if (!sKeywordFilter.isEmpty())
307 sSQL +=
"AND (program.title LIKE :Keyword1 "
308 "OR program.subtitle LIKE :Keyword2 "
309 "OR program.description LIKE :Keyword3) ";
311 QString filter = QString(
"%%1%").arg(sKeywordFilter);
312 bindings[
":Keyword1"] = filter;
313 bindings[
":Keyword2"] = filter;
314 bindings[
":Keyword3"] = filter;
317 if (sSort ==
"starttime")
318 sSQL +=
"ORDER BY program.starttime ";
319 else if (sSort ==
"title")
320 sSQL +=
"ORDER BY program.title ";
321 else if (sSort ==
"channel")
322 sSQL +=
"ORDER BY channel.channum ";
323 else if (sSort ==
"duration")
324 sSQL +=
"ORDER BY (program.endtime - program.starttime) ";
326 sSQL +=
"ORDER BY program.starttime ";
345 uint nTotalAvailable = 0;
347 (
uint)nStartIndex, (
uint)nCount, nTotalAvailable);
355 nCount = (int)progList.
size();
356 int nEndIndex = (int)progList.
size();
358 for(
int n = 0; n < nEndIndex; n++)
362 V2Program *pProgram = pPrograms->AddNewProgram();
369 pPrograms->setStartIndex ( nStartIndex );
370 pPrograms->setCount ( nCount );
371 pPrograms->setTotalAvailable( nTotalAvailable );
373 pPrograms->setVersion ( MYTH_BINARY_VERSION );
374 pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
384 const QDateTime &rawStartTime )
388 throw QString(
"Channel ID is invalid" );
389 if (!rawStartTime.isValid())
390 throw QString(
"StartTime is invalid" );
392 QDateTime dtStartTime = rawStartTime.toUTC();
422 if (sFileName.isEmpty())
424 LOG(VB_UPNP, LOG_ERR,
425 QString(
"GetImageFile - ChanId %1 doesn't exist or isn't visible")
435 QString sFullFileName = storage.
FindFile( sFileName );
437 if (sFullFileName.isEmpty())
439 LOG(VB_UPNP, LOG_ERR,
440 QString(
"GetImageFile - Unable to find %1.").arg(sFileName));
449 if ((nWidth == 0) && (nHeight == 0))
451 if (QFile::exists( sFullFileName ))
453 return QFileInfo( sFullFileName );
456 LOG(VB_UPNP, LOG_ERR,
457 QString(
"GetImageFile - File Does not exist %1.").arg(sFullFileName));
463 QString sNewFileName = QString(
"%1.%2x%3.png" )
464 .arg( sFullFileName )
472 if (QFile::exists( sNewFileName ))
473 return QFileInfo( sNewFileName );
479 QString sChannelsDirectory = QFileInfo( sNewFileName ).absolutePath();
481 if (!QFileInfo( sChannelsDirectory ).isWritable())
483 LOG(VB_UPNP, LOG_ERR, QString(
"GetImageFile - no write access to: %1")
484 .arg( sChannelsDirectory ));
488 auto *pImage =
new QImage( sFullFileName );
492 LOG(VB_UPNP, LOG_ERR, QString(
"GetImageFile - can't create image: %1")
493 .arg( sFullFileName ));
497 float fAspect = (float)(pImage->width()) / pImage->height();
500 LOG(VB_UPNP, LOG_ERR, QString(
"GetImageFile - zero aspect"));
506 nWidth = (int)std::rint(nHeight * fAspect);
509 nHeight = (int)std::rint(nWidth / fAspect);
511 QImage img = pImage->scaled( nWidth, nHeight, Qt::IgnoreAspectRatio,
512 Qt::SmoothTransformation);
516 LOG(VB_UPNP, LOG_ERR, QString(
"SaveImageFile - unable to scale. "
517 "See if %1 is really an image.").arg( sFullFileName ));
522 if (!img.save( sNewFileName,
"PNG" ))
524 LOG(VB_UPNP, LOG_ERR, QString(
"SaveImageFile - failed, %1")
525 .arg( sNewFileName ));
532 return QFileInfo( sNewFileName );
544 ChannelGroupList::iterator it;
545 for (it = list.begin(); it < list.end(); ++it)
563 query.
prepare(
"SELECT DISTINCT category FROM program WHERE category != '' "
564 "ORDER BY category");
571 catList << query.
value(0).toString();
583 QStringList keywordList;
594 query.
prepare(
"SELECT DISTINCT phrase FROM keyword "
595 "WHERE searchtype = :TYPE "
597 query.
bindValue(
":TYPE",
static_cast<int>(iType));
604 keywordList << query.
value(0).toString();
617 bool bResult =
false;
620 throw QString(
"Channel ID is invalid" );
634 bool bResult =
false;
637 throw QString(
"Channel ID is invalid" );