MythTV  master
v2guide.cpp
Go to the documentation of this file.
1 // Program Name: guide.cpp
3 // Created : Mar. 7, 2011
4 //
5 // Copyright (c) 2011 David Blain <dblain@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 // C++
27 #include <cmath>
28 
29 // MythTV
30 #include "libmythbase/compat.h"
34 #include "libmythbase/mythversion.h"
36 #include "libmythtv/channelgroup.h"
37 #include "libmythtv/channelutil.h"
38 
39 // MythBackend
40 #include "autoexpire.h"
41 #include "scheduler.h"
42 #include "v2artworkInfoList.h"
43 #include "v2castMemberList.h"
44 #include "v2guide.h"
45 
46 // Qt6 has made the QFileInfo::QFileInfo(QString) constructor
47 // explicit, which means that it is no longer possible to use an
48 // initializer list to construct a QFileInfo. Disable that clang-tidy
49 // check for this file so it can still be run on the rest of the file
50 // in the project.
51 //
52 // NOLINTBEGIN(modernize-return-braced-init-list)
53 
54 extern AutoExpire *expirer;
55 extern Scheduler *sched;
56 
58 //
60 
61 // This will be initialised in a thread safe manner on first use
63  (GUIDE_HANDLE, V2Guide::staticMetaObject, &V2Guide::RegisterCustomTypes))
64 
66 {
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");
78 }
79 
81 {
82 }
83 
84 V2ProgramGuide *V2Guide::GetProgramGuide( const QDateTime &rawStartTime,
85  const QDateTime &rawEndTime,
86  bool bDetails,
87  int nChannelGroupId,
88  int nStartIndex,
89  int nCount,
90  bool bWithInvisible)
91 {
92  if (!rawStartTime.isValid())
93  throw QString( "StartTime is invalid" );
94 
95  if (!rawEndTime.isValid())
96  throw QString( "EndTime is invalid" );
97 
98  QDateTime dtStartTime = rawStartTime.toUTC();
99  QDateTime dtEndTime = rawEndTime.toUTC();
100 
101  if (dtEndTime < dtStartTime)
102  throw QString( "EndTime is before StartTime");
103 
104  if (nStartIndex <= 0)
105  nStartIndex = 0;
106 
107  if (nCount <= 0)
108  nCount = 20000;
109 
110  // ----------------------------------------------------------------------
111  // Load the channel list
112  // ----------------------------------------------------------------------
113 
114  uint nTotalAvailable = 0;
115  ChannelInfoList chanList = ChannelUtil::LoadChannels(nStartIndex, nCount,
116  nTotalAvailable,
117  !bWithInvisible,
120  0,
121  nChannelGroupId);
122 
123  // ----------------------------------------------------------------------
124  // Build SQL statement for Program Listing
125  // ----------------------------------------------------------------------
126 
127  ProgramList schedList;
128  MSqlBindings bindings;
129 
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"; // Omit 'manual' recordings scheds
135 
136 #if 0
137  QString sGroupBy = "program.starttime, channel.channum,"
138  "channel.callsign, program.title";
139 #endif
140 
141  QString sOrderBy = "program.starttime";
142 
143  bindings[":STARTDATE" ] = dtStartTime;
144  bindings[":STARTDATELIMIT"] = dtStartTime.addDays(-1);
145  bindings[":ENDDATE" ] = dtEndTime;
146 
147  // ----------------------------------------------------------------------
148  // Get all Pending Scheduled Programs
149  // ----------------------------------------------------------------------
150 
151  // NOTE: Fetching this information directly from the schedule is
152  // significantly faster than using ProgramInfo::LoadFromScheduler()
153  auto *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler());
154  if (scheduler)
155  scheduler->GetAllPending(schedList);
156 
157  // ----------------------------------------------------------------------
158  // Build Response
159  // ----------------------------------------------------------------------
160 
161  auto *pGuide = new V2ProgramGuide();
162 
163  ChannelInfoList::iterator chan_it;
164  for (chan_it = chanList.begin(); chan_it != chanList.end(); ++chan_it)
165  {
166  // Create ChannelInfo Object
167  V2ChannelInfo *pChannel = pGuide->AddNewChannel();
168  V2FillChannelInfo( pChannel, (*chan_it), bDetails );
169 
170  // Load the list of programmes for this channel
171  ProgramList progList;
172  bindings[":CHANID"] = (*chan_it).m_chanId;
173  LoadFromProgram( progList, sWhere, sOrderBy, sOrderBy, bindings,
174  schedList );
175 
176  // Create Program objects and add them to the channel object
177  ProgramList::iterator progIt;
178  for( progIt = progList.begin(); progIt != progList.end(); ++progIt)
179  {
180  V2Program *pProgram = pChannel->AddNewProgram();
181  V2FillProgramInfo( pProgram, *progIt, false, bDetails, false ); // No cast info
182  }
183  }
184 
185  // ----------------------------------------------------------------------
186 
187  pGuide->setStartTime ( dtStartTime );
188  pGuide->setEndTime ( dtEndTime );
189  pGuide->setDetails ( bDetails );
190 
191  pGuide->setStartIndex ( nStartIndex );
192  pGuide->setCount ( chanList.size() );
193  pGuide->setTotalAvailable( nTotalAvailable );
194  pGuide->setAsOf ( MythDate::current() );
195 
196  pGuide->setVersion ( MYTH_BINARY_VERSION );
197  pGuide->setProtoVer ( MYTH_PROTO_VERSION );
198 
199  return pGuide;
200 }
201 
203 //
205 
207  int nCount,
208  const QDateTime& rawStartTime,
209  const QDateTime& rawEndTime,
210  int nChanId,
211  const QString& sTitleFilter,
212  const QString& sCategoryFilter,
213  const QString& sPersonFilter,
214  const QString& sKeywordFilter,
215  bool bOnlyNew,
216  bool bDetails,
217  const QString &sSort,
218  bool bDescending,
219  bool bWithInvisible)
220 {
221  if (!rawStartTime.isNull() && !rawStartTime.isValid())
222  throw QString( "StartTime is invalid" );
223 
224  if (!rawEndTime.isNull() && !rawEndTime.isValid())
225  throw QString( "EndTime is invalid" );
226 
227  QDateTime dtStartTime = rawStartTime;
228  const QDateTime& dtEndTime = rawEndTime;
229 
230  if (!rawEndTime.isNull() && dtEndTime < dtStartTime)
231  throw QString( "EndTime is before StartTime");
232 
233  MSqlQuery query(MSqlQuery::InitCon());
234 
235 
236  // ----------------------------------------------------------------------
237  // Build SQL statement for Program Listing
238  // ----------------------------------------------------------------------
239 
240  ProgramList progList;
241  ProgramList schedList;
242  MSqlBindings bindings;
243 
244  QString sSQL;
245 
246  if (!sPersonFilter.isEmpty())
247  {
248  sSQL = ", people, credits " // LEFT JOIN
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);
254  }
255  else
256  sSQL = "WHERE ";
257 
258  if (bOnlyNew)
259  {
260  sSQL = "LEFT JOIN oldprogram ON oldprogram.oldtitle = program.title "
261  + sSQL
262  + "oldprogram.oldtitle IS NULL AND ";
263  }
264 
265  sSQL += "deleted IS NULL AND ";
266 
267  if (!bWithInvisible)
268  sSQL += "visible > 0 AND ";
269 
270  sSQL += "program.manualid = 0 "; // Exclude programmes created purely for 'manual' recording schedules
271 
272  if (nChanId < 0)
273  nChanId = 0;
274 
275  if (nChanId > 0)
276  {
277  sSQL += "AND program.chanid = :ChanId ";
278  bindings[":ChanId"] = nChanId;
279  }
280 
281  if (dtStartTime.isNull())
282  dtStartTime = QDateTime::currentDateTimeUtc();
283 
284  sSQL += " AND program.endtime >= :StartDate ";
285  bindings[":StartDate"] = dtStartTime;
286 
287  if (!dtEndTime.isNull())
288  {
289  sSQL += "AND program.starttime <= :EndDate ";
290  bindings[":EndDate"] = dtEndTime;
291  }
292 
293  if (!sTitleFilter.isEmpty())
294  {
295  sSQL += "AND program.title LIKE :Title ";
296  bindings[":Title"] = QString("%%1%").arg(sTitleFilter);
297  }
298 
299  if (!sCategoryFilter.isEmpty())
300  {
301  sSQL += "AND program.category LIKE :Category ";
302  bindings[":Category"] = sCategoryFilter;
303  }
304 
305  if (!sKeywordFilter.isEmpty())
306  {
307  sSQL += "AND (program.title LIKE :Keyword1 "
308  "OR program.subtitle LIKE :Keyword2 "
309  "OR program.description LIKE :Keyword3) ";
310 
311  QString filter = QString("%%1%").arg(sKeywordFilter);
312  bindings[":Keyword1"] = filter;
313  bindings[":Keyword2"] = filter;
314  bindings[":Keyword3"] = filter;
315  }
316 
317  if (sSort == "starttime")
318  sSQL += "ORDER BY program.starttime "; // NOLINT(bugprone-branch-clone)
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) ";
325  else
326  sSQL += "ORDER BY program.starttime ";
327 
328  if (bDescending)
329  sSQL += "DESC ";
330  else
331  sSQL += "ASC ";
332 
333  // ----------------------------------------------------------------------
334  // Get all Pending Scheduled Programs
335  // ----------------------------------------------------------------------
336 
337  // NOTE: Fetching this information directly from the schedule is
338  // significantly faster than using ProgramInfo::LoadFromScheduler()
339  auto *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler());
340  if (scheduler)
341  scheduler->GetAllPending(schedList);
342 
343  // ----------------------------------------------------------------------
344 
345  uint nTotalAvailable = 0;
346  LoadFromProgram( progList, sSQL, bindings, schedList,
347  (uint)nStartIndex, (uint)nCount, nTotalAvailable);
348 
349  // ----------------------------------------------------------------------
350  // Build Response
351  // ----------------------------------------------------------------------
352 
353  auto *pPrograms = new V2ProgramList();
354 
355  nCount = (int)progList.size();
356  int nEndIndex = (int)progList.size();
357 
358  for( int n = 0; n < nEndIndex; n++)
359  {
360  ProgramInfo *pInfo = progList[ n ];
361 
362  V2Program *pProgram = pPrograms->AddNewProgram();
363 
364  V2FillProgramInfo( pProgram, pInfo, true, bDetails, false ); // No cast info, loading this takes far too long
365  }
366 
367  // ----------------------------------------------------------------------
368 
369  pPrograms->setStartIndex ( nStartIndex );
370  pPrograms->setCount ( nCount );
371  pPrograms->setTotalAvailable( nTotalAvailable );
372  pPrograms->setAsOf ( MythDate::current() );
373  pPrograms->setVersion ( MYTH_BINARY_VERSION );
374  pPrograms->setProtoVer ( MYTH_PROTO_VERSION );
375 
376  return pPrograms;
377 }
378 
380 //
382 
384  const QDateTime &rawStartTime )
385 
386 {
387  if (!(nChanId > 0))
388  throw QString( "Channel ID is invalid" );
389  if (!rawStartTime.isValid())
390  throw QString( "StartTime is invalid" );
391 
392  QDateTime dtStartTime = rawStartTime.toUTC();
393 
394  // ----------------------------------------------------------------------
395  // -=>TODO: Add support for getting Recorded Program Info
396  // ----------------------------------------------------------------------
397 
398  // Build Response
399 
400  auto *pProgram = new V2Program();
401  ProgramInfo *pInfo = LoadProgramFromProgram(nChanId, dtStartTime);
402 
403  V2FillProgramInfo( pProgram, pInfo, true, true, true );
404 
405  delete pInfo;
406 
407  return pProgram;
408 }
409 
411 //
413 
414 QFileInfo V2Guide::GetChannelIcon( int nChanId,
415  int nWidth /* = 0 */,
416  int nHeight /* = 0 */ )
417 {
418  // Get Icon file path
419 
420  QString sFileName = ChannelUtil::GetIcon( nChanId );
421 
422  if (sFileName.isEmpty())
423  {
424  LOG(VB_UPNP, LOG_ERR,
425  QString("GetImageFile - ChanId %1 doesn't exist or isn't visible")
426  .arg(nChanId));
427  return {};
428  }
429 
430  // ------------------------------------------------------------------
431  // Search for the filename
432  // ------------------------------------------------------------------
433 
434  StorageGroup storage( "ChannelIcons" );
435  QString sFullFileName = storage.FindFile( sFileName );
436 
437  if (sFullFileName.isEmpty())
438  {
439  LOG(VB_UPNP, LOG_ERR,
440  QString("GetImageFile - Unable to find %1.").arg(sFileName));
441 
442  return {};
443  }
444 
445  // ----------------------------------------------------------------------
446  // check to see if the file (still) exists
447  // ----------------------------------------------------------------------
448 
449  if ((nWidth == 0) && (nHeight == 0))
450  {
451  if (QFile::exists( sFullFileName ))
452  {
453  return QFileInfo( sFullFileName );
454  }
455 
456  LOG(VB_UPNP, LOG_ERR,
457  QString("GetImageFile - File Does not exist %1.").arg(sFullFileName));
458 
459  return {};
460  }
461  // -------------------------------------------------------------------
462 
463  QString sNewFileName = QString( "%1.%2x%3.png" )
464  .arg( sFullFileName )
465  .arg( nWidth )
466  .arg( nHeight );
467 
468  // ----------------------------------------------------------------------
469  // check to see if image is already created.
470  // ----------------------------------------------------------------------
471 
472  if (QFile::exists( sNewFileName ))
473  return QFileInfo( sNewFileName );
474 
475  // ----------------------------------------------------------------------
476  // We need to create it...
477  // ----------------------------------------------------------------------
478 
479  QString sChannelsDirectory = QFileInfo( sNewFileName ).absolutePath();
480 
481  if (!QFileInfo( sChannelsDirectory ).isWritable())
482  {
483  LOG(VB_UPNP, LOG_ERR, QString("GetImageFile - no write access to: %1")
484  .arg( sChannelsDirectory ));
485  return {};
486  }
487 
488  auto *pImage = new QImage( sFullFileName );
489 
490  if (!pImage)
491  {
492  LOG(VB_UPNP, LOG_ERR, QString("GetImageFile - can't create image: %1")
493  .arg( sFullFileName ));
494  return {};
495  }
496 
497  float fAspect = (float)(pImage->width()) / pImage->height();
498  if (fAspect == 0)
499  {
500  LOG(VB_UPNP, LOG_ERR, QString("GetImageFile - zero aspect"));
501  delete pImage;
502  return {};
503  }
504 
505  if ( nWidth == 0 )
506  nWidth = (int)std::rint(nHeight * fAspect);
507 
508  if ( nHeight == 0 )
509  nHeight = (int)std::rint(nWidth / fAspect);
510 
511  QImage img = pImage->scaled( nWidth, nHeight, Qt::IgnoreAspectRatio,
512  Qt::SmoothTransformation);
513 
514  if (img.isNull())
515  {
516  LOG(VB_UPNP, LOG_ERR, QString("SaveImageFile - unable to scale. "
517  "See if %1 is really an image.").arg( sFullFileName ));
518  delete pImage;
519  return {};
520  }
521 
522  if (!img.save( sNewFileName, "PNG" ))
523  {
524  LOG(VB_UPNP, LOG_ERR, QString("SaveImageFile - failed, %1")
525  .arg( sNewFileName ));
526  delete pImage;
527  return {};
528  }
529 
530  delete pImage;
531 
532  return QFileInfo( sNewFileName );
533 }
534 
536 //
538 
540 {
541  ChannelGroupList list = ChannelGroup::GetChannelGroups(bIncludeEmpty);
542  auto *pGroupList = new V2ChannelGroupList();
543 
544  ChannelGroupList::iterator it;
545  for (it = list.begin(); it < list.end(); ++it)
546  {
547  V2ChannelGroup *pGroup = pGroupList->AddNewChannelGroup();
548  V2FillChannelGroup(pGroup, (*it));
549  }
550 
551  return pGroupList;
552 }
553 
555 //
557 
558 QStringList V2Guide::GetCategoryList( ) //int nStartIndex, int nCount)
559 {
560  QStringList catList;
561  MSqlQuery query(MSqlQuery::InitCon());
562 
563  query.prepare("SELECT DISTINCT category FROM program WHERE category != '' "
564  "ORDER BY category");
565 
566  if (!query.exec())
567  return catList;
568 
569  while (query.next())
570  {
571  catList << query.value(0).toString();
572  }
573 
574  return catList;
575 }
576 
578 //
580 
581 QStringList V2Guide::GetStoredSearches( const QString& sType )
582 {
583  QStringList keywordList;
584  MSqlQuery query(MSqlQuery::InitCon());
585 
586  RecSearchType iType = searchTypeFromString(sType);
587 
588  if (iType == kNoSearch)
589  {
590  //throw QString( "Invalid Type" );
591  return keywordList;
592  }
593 
594  query.prepare("SELECT DISTINCT phrase FROM keyword "
595  "WHERE searchtype = :TYPE "
596  "ORDER BY phrase");
597  query.bindValue(":TYPE", static_cast<int>(iType));
598 
599  if (!query.exec())
600  return keywordList;
601 
602  while (query.next())
603  {
604  keywordList << query.value(0).toString();
605  }
606 
607  return keywordList;
608 }
609 
611 //
613 
614 bool V2Guide::AddToChannelGroup ( int nChannelGroupId,
615  int nChanId )
616 {
617  bool bResult = false;
618 
619  if (!(nChanId > 0))
620  throw QString( "Channel ID is invalid" );
621 
622  bResult = ChannelGroup::AddChannel(nChanId, nChannelGroupId);
623 
624  return bResult;
625 }
626 
628 //
630 
631 bool V2Guide::RemoveFromChannelGroup ( int nChannelGroupId,
632  int nChanId )
633 {
634  bool bResult = false;
635 
636  if (!(nChanId > 0))
637  throw QString( "Channel ID is invalid" );
638 
639  bResult = ChannelGroup::DeleteChannel(nChanId, nChannelGroupId);
640 
641  return bResult;
642 }
643 
644 // NOLINTEND(modernize-return-braced-init-list)
MSqlBindings
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:101
Scheduler
Definition: scheduler.h:45
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:807
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
Q_GLOBAL_STATIC_WITH_ARGS
Q_GLOBAL_STATIC_WITH_ARGS(MythHTTPMetaService, s_service,(GUIDE_HANDLE, V2Guide::staticMetaObject, &V2Guide::RegisterCustomTypes)) void V2Guide
Definition: v2guide.cpp:62
V2FillProgramInfo
void V2FillProgramInfo(V2Program *pProgram, ProgramInfo *pInfo, bool bIncChannel, bool bDetails, bool bIncCast, bool bIncArtwork, bool bIncRecording)
Definition: v2serviceUtil.cpp:21
MythCoreContext::GetScheduler
MythScheduler * GetScheduler(void)
Definition: mythcorecontext.cpp:1875
LoadProgramFromProgram
ProgramInfo * LoadProgramFromProgram(const uint chanid, const QDateTime &starttime)
Definition: programinfo.cpp:5794
V2ProgramGuide
Definition: v2programGuide.h:31
ChannelUtil::LoadChannels
static ChannelInfoList LoadChannels(uint startIndex, uint count, uint &totalAvailable, bool ignoreHidden=true, OrderBy orderBy=kChanOrderByChanNum, GroupBy groupBy=kChanGroupByChanid, uint sourceID=0, uint channelGroupID=0, bool liveTVOnly=false, const QString &callsign="", const QString &channum="", bool ignoreUntunable=true)
Load channels from database into a list of ChannelInfo objects.
Definition: channelutil.cpp:2430
searchTypeFromString
RecSearchType searchTypeFromString(const QString &type)
Definition: recordingtypes.cpp:329
StorageGroup::FindFile
QString FindFile(const QString &filename)
Definition: storagegroup.cpp:602
sched
Scheduler * sched
ChannelGroup::AddChannel
static bool AddChannel(uint chanid, int changrpid)
Definition: channelgroup.cpp:71
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:205
V2ChannelGroup
Definition: v2channelGroup.h:19
AutoExpire
Used to expire recordings to make space for new recordings.
Definition: autoexpire.h:60
V2ProgramList
Definition: v2programList.h:22
mythhttpmetaservice.h
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:608
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
V2Guide::V2Guide
V2Guide()
Definition: v2guide.cpp:80
ChannelGroup::GetChannelGroups
static ChannelGroupList GetChannelGroups(bool includeEmpty=true)
Definition: channelgroup.cpp:328
scheduler.h
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
AutoDeleteDeque::begin
iterator begin(void)
Definition: autodeletedeque.h:50
autoexpire.h
mythlogging.h
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:540
compat.h
V2Guide::RemoveFromChannelGroup
static bool RemoveFromChannelGroup(int ChannelGroupId, int ChanId)
Definition: v2guide.cpp:631
V2Guide::GetProgramGuide
static V2ProgramGuide * GetProgramGuide(const QDateTime &StartTime, const QDateTime &EndTime, bool Details, int ChannelGroupId, int StartIndex, int Count, bool WithInvisible)
Definition: v2guide.cpp:84
RecSearchType
RecSearchType
Definition: recordingtypes.h:78
V2FillChannelGroup
void V2FillChannelGroup(V2ChannelGroup *pGroup, const ChannelGroupItem &pGroupItem)
Definition: v2serviceUtil.cpp:223
storagegroup.h
V2ChannelGroupList
Definition: v2channelGroupList.h:13
V2FillChannelInfo
bool V2FillChannelInfo(V2ChannelInfo *pChannel, uint nChanID, bool bDetails)
Definition: v2serviceUtil.cpp:143
kNoSearch
@ kNoSearch
Definition: recordingtypes.h:80
ChannelGroupList
std::vector< ChannelGroupItem > ChannelGroupList
Definition: channelgroup.h:31
uint
unsigned int uint
Definition: compat.h:79
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:54
AutoDeleteDeque::end
iterator end(void)
Definition: autodeletedeque.h:51
MythHTTPService
Definition: mythhttpservice.h:19
channelutil.h
v2artworkInfoList.h
AutoDeleteDeque< ProgramInfo * >
V2Guide::RegisterCustomTypes
static void RegisterCustomTypes()
V2Guide::GetProgramList
static V2ProgramList * GetProgramList(int StartIndex, int Count, const QDateTime &StartTime, const QDateTime &EndTime, int ChanId, const QString &TitleFilter, const QString &CategoryFilter, const QString &PersonFilter, const QString &KeywordFilter, bool OnlyNew, bool Details, const QString &Sort, bool Descending, bool WithInvisible)
Definition: v2guide.cpp:206
V2ChannelInfo::AddNewProgram
V2Program * AddNewProgram()
Definition: v2programAndChannel.h:203
ChannelUtil::GetIcon
static QString GetIcon(uint chanid)
Definition: channelutil.cpp:1245
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:67
channelgroup.h
mythcorecontext.h
V2Guide::GetChannelIcon
static QFileInfo GetChannelIcon(int ChanId, int Width, int Height)
Definition: v2guide.cpp:414
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:883
V2Guide::AddToChannelGroup
static bool AddToChannelGroup(int ChannelGroupId, int ChanId)
Definition: v2guide.cpp:614
LoadFromProgram
bool LoadFromProgram(ProgramList &destination, const QString &where, const QString &groupBy, const QString &orderBy, const MSqlBindings &bindings, const ProgramList &schedList)
Definition: programinfo.cpp:5642
ChannelUtil::kChanGroupByCallsignAndChannum
@ kChanGroupByCallsignAndChannum
Definition: channelutil.h:208
V2Guide::GetChannelGroupList
static V2ChannelGroupList * GetChannelGroupList(bool IncludeEmpty)
Definition: v2guide.cpp:539
V2Program
Definition: v2programAndChannel.h:98
V2Guide::GetCategoryList
static QStringList GetCategoryList()
Definition: v2guide.cpp:558
v2guide.h
StorageGroup
Definition: storagegroup.h:11
Scheduler::GetAllPending
bool GetAllPending(RecList &retList, int recRuleId=0) const
Definition: scheduler.cpp:1741
expirer
AutoExpire * expirer
V2Guide::GetProgramDetails
static V2Program * GetProgramDetails(int ChanId, const QDateTime &StartTime)
Definition: v2guide.cpp:383
AutoDeleteDeque< ProgramInfo * >::iterator
typename List::iterator iterator
Definition: autodeletedeque.h:15
v2castMemberList.h
GUIDE_HANDLE
#define GUIDE_HANDLE
Definition: v2guide.h:41
MythHTTPMetaService
Definition: mythhttpmetaservice.h:10
V2ChannelInfo
Definition: v2programAndChannel.h:27
AutoDeleteDeque::size
size_t size(void) const
Definition: autodeletedeque.h:67
ChannelUtil::kChanOrderByChanNum
@ kChanOrderByChanNum
Definition: channelutil.h:200
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:832
ChannelInfoList
std::vector< ChannelInfo > ChannelInfoList
Definition: channelinfo.h:131
V2Guide::GetStoredSearches
static QStringList GetStoredSearches(const QString &Type)
Definition: v2guide.cpp:581
ChannelGroup::DeleteChannel
static bool DeleteChannel(uint chanid, int changrpid)
Definition: channelgroup.cpp:150