MythTV  0.27pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
channel.cpp
Go to the documentation of this file.
1 
2 // Program Name: channel.cpp
3 // Created : Apr. 8, 2011
4 //
5 // Copyright (c) 2011 Robert McNamara <rmcnamara@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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 #include <QList>
27 
28 #include <math.h>
29 
30 #include "channel.h"
31 
32 #include "compat.h"
33 #include "mythdbcon.h"
34 #include "mythdirs.h"
35 #include "mythversion.h"
36 #include "mythcorecontext.h"
37 #include "channelutil.h"
38 #include "sourceutil.h"
39 #include "cardutil.h"
40 #include "datadirect.h"
41 #include "mythdate.h"
42 
43 #include "serviceUtil.h"
44 
46 //
48 
50  int nStartIndex,
51  int nCount )
52 {
53  vector<uint> chanList;
54 
55  chanList = ChannelUtil::GetChanIDs(nSourceID);
56 
57  // ----------------------------------------------------------------------
58  // Build Response
59  // ----------------------------------------------------------------------
60 
61  DTC::ChannelInfoList *pChannelInfos = new DTC::ChannelInfoList();
62 
63  nStartIndex = min( nStartIndex, (int)chanList.size() );
64  nCount = (nCount > 0) ? min( nCount, (int)chanList.size() ) : chanList.size();
65  int nEndIndex = min((nStartIndex + nCount), (int)chanList.size() );
66 
67  for( int n = nStartIndex; n < nEndIndex; n++)
68  {
69  DTC::ChannelInfo *pChannelInfo = pChannelInfos->AddNewChannelInfo();
70 
71  int chanid = chanList.at(n);
72  QString channum = ChannelUtil::GetChanNum(chanid);
73  QString format, modulation, freqtable, freqid, dtv_si_std,
74  xmltvid, default_authority, icon;
75  int finetune, program_number;
76  uint64_t frequency;
77  uint atscmajor, atscminor, transportid, networkid, mplexid;
78  bool commfree = false;
79  bool eit = false;
80  bool visible = true;
81 
82  if (ChannelUtil::GetExtendedChannelData( nSourceID, channum, format, modulation,
83  freqtable, freqid, finetune, frequency,
84  dtv_si_std, program_number, atscmajor,
85  atscminor, transportid, networkid, mplexid,
86  commfree, eit, visible, xmltvid, default_authority, icon ))
87  {
88  pChannelInfo->setChanId(chanid);
89  pChannelInfo->setChanNum(channum);
90  pChannelInfo->setCallSign(ChannelUtil::GetCallsign(chanid));
91  pChannelInfo->setIconURL(icon);
92  pChannelInfo->setChannelName(ChannelUtil::GetServiceName(chanid));
93  pChannelInfo->setMplexId(mplexid);
94  pChannelInfo->setServiceId(program_number);
95  pChannelInfo->setATSCMajorChan(atscmajor);
96  pChannelInfo->setATSCMinorChan(atscminor);
97  pChannelInfo->setFormat(format);
98  pChannelInfo->setModulation(modulation);
99  pChannelInfo->setFrequencyTable(freqtable);
100  pChannelInfo->setFineTune(finetune);
101  pChannelInfo->setFrequency((long)frequency);
102  pChannelInfo->setFrequencyId(freqid);
103  pChannelInfo->setSIStandard(dtv_si_std);
104  pChannelInfo->setTransportId(transportid);
105  pChannelInfo->setNetworkId(networkid);
106  pChannelInfo->setChanFilters(ChannelUtil::GetVideoFilters(nSourceID, channum));
107  pChannelInfo->setSourceId(nSourceID);
108  pChannelInfo->setCommFree(commfree);
109  pChannelInfo->setUseEIT(eit);
110  pChannelInfo->setVisible(visible);
111  pChannelInfo->setXMLTVID(xmltvid);
112  pChannelInfo->setDefaultAuth(default_authority);
113  }
114  }
115 
116  int curPage = 0, totalPages = 0;
117  if (nCount == 0)
118  totalPages = 1;
119  else
120  totalPages = (int)ceil((float)chanList.size() / nCount);
121 
122  if (totalPages == 1)
123  curPage = 1;
124  else
125  {
126  curPage = (int)ceil((float)nStartIndex / nCount) + 1;
127  }
128 
129  pChannelInfos->setStartIndex ( nStartIndex );
130  pChannelInfos->setCount ( nCount );
131  pChannelInfos->setCurrentPage ( curPage );
132  pChannelInfos->setTotalPages ( totalPages );
133  pChannelInfos->setTotalAvailable( chanList.size() );
134  pChannelInfos->setAsOf ( MythDate::current() );
135  pChannelInfos->setVersion ( MYTH_BINARY_VERSION );
136  pChannelInfos->setProtoVer ( MYTH_PROTO_VERSION );
137 
138  return pChannelInfos;
139 }
140 
142 //
144 
146 {
147  if (nChanID == 0)
148  throw( QString("Channel ID appears invalid."));
149 
150  DTC::ChannelInfo *pChannelInfo = new DTC::ChannelInfo();
151 
152  QString channum = ChannelUtil::GetChanNum(nChanID);
153  uint sourceid = ChannelUtil::GetSourceIDForChannel(nChanID);
154  QString format, modulation, freqtable, freqid, dtv_si_std,
155  xmltvid, default_authority, icon;
156  int finetune, program_number;
157  uint64_t frequency;
158  uint atscmajor, atscminor, transportid, networkid, mplexid;
159  bool commfree = false;
160  bool eit = false;
161  bool visible = true;
162 
163  if (ChannelUtil::GetExtendedChannelData( sourceid, channum, format, modulation,
164  freqtable, freqid, finetune, frequency,
165  dtv_si_std, program_number, atscmajor,
166  atscminor, transportid, networkid, mplexid,
167  commfree, eit, visible, xmltvid, default_authority, icon ))
168  {
169  pChannelInfo->setChanId(nChanID);
170  pChannelInfo->setChanNum(channum);
171  pChannelInfo->setCallSign(ChannelUtil::GetCallsign(nChanID));
172  pChannelInfo->setIconURL(icon);
173  pChannelInfo->setChannelName(ChannelUtil::GetServiceName(nChanID));
174  pChannelInfo->setMplexId(mplexid);
175  pChannelInfo->setServiceId(program_number);
176  pChannelInfo->setATSCMajorChan(atscmajor);
177  pChannelInfo->setATSCMinorChan(atscminor);
178  pChannelInfo->setFormat(format);
179  pChannelInfo->setModulation(modulation);
180  pChannelInfo->setFrequencyTable(freqtable);
181  pChannelInfo->setFineTune(finetune);
182  pChannelInfo->setFrequency((long)frequency);
183  pChannelInfo->setFrequencyId(freqid);
184  pChannelInfo->setSIStandard(dtv_si_std);
185  pChannelInfo->setTransportId(transportid);
186  pChannelInfo->setNetworkId(networkid);
187  pChannelInfo->setChanFilters(ChannelUtil::GetVideoFilters(sourceid, channum));
188  pChannelInfo->setSourceId(sourceid);
189  pChannelInfo->setCommFree(commfree);
190  pChannelInfo->setUseEIT(eit);
191  pChannelInfo->setVisible(visible);
192  pChannelInfo->setXMLTVID(xmltvid);
193  pChannelInfo->setDefaultAuth(default_authority);
194  }
195  else
196  throw( QString("Channel ID appears invalid."));
197 
198  return pChannelInfo;
199 }
200 
202  uint SourceID,
203  uint ChannelID,
204  const QString &CallSign,
205  const QString &ChannelName,
206  const QString &ChannelNumber,
207  uint ServiceID,
208  uint ATSCMajorChannel,
209  uint ATSCMinorChannel,
210  bool UseEIT,
211  bool visible,
212  const QString &FrequencyID,
213  const QString &Icon,
214  const QString &Format,
215  const QString &XMLTVID,
216  const QString &DefaultAuthority )
217 {
218  bool bResult = false;
219 
220  bResult = ChannelUtil::UpdateChannel( MplexID, SourceID, ChannelID,
221  CallSign, ChannelName, ChannelNumber,
222  ServiceID, ATSCMajorChannel, ATSCMinorChannel,
223  UseEIT, !visible, false, FrequencyID,
224  Icon, Format, XMLTVID, DefaultAuthority );
225 
226  return bResult;
227 }
228 
230  uint SourceID,
231  uint ChannelID,
232  const QString &CallSign,
233  const QString &ChannelName,
234  const QString &ChannelNumber,
235  uint ServiceID,
236  uint ATSCMajorChannel,
237  uint ATSCMinorChannel,
238  bool UseEIT,
239  bool visible,
240  const QString &FrequencyID,
241  const QString &Icon,
242  const QString &Format,
243  const QString &XMLTVID,
244  const QString &DefaultAuthority )
245 {
246  bool bResult = false;
247 
248  bResult = ChannelUtil::CreateChannel( MplexID, SourceID, ChannelID,
249  CallSign, ChannelName, ChannelNumber,
250  ServiceID, ATSCMajorChannel, ATSCMinorChannel,
251  UseEIT, !visible, false, FrequencyID,
252  Icon, Format, XMLTVID, DefaultAuthority );
253 
254  return bResult;
255 }
256 
257 bool Channel::RemoveDBChannel( uint nChannelID )
258 {
259  bool bResult = false;
260 
261  bResult = ChannelUtil::DeleteChannel( nChannelID );
262 
263  return bResult;
264 }
265 
267 //
269 
271 {
272  MSqlQuery query(MSqlQuery::InitCon());
273 
274  if (!query.isConnected())
275  throw( QString("Database not open while trying to list "
276  "Video Sources."));
277 
278  query.prepare("SELECT sourceid, name, xmltvgrabber, userid, "
279  "freqtable, lineupid, password, useeit, configpath, "
280  "dvb_nit_id FROM videosource "
281  "ORDER BY sourceid" );
282 
283  if (!query.exec())
284  {
285  MythDB::DBError("MythAPI::GetVideoSourceList()", query);
286 
287  throw( QString( "Database Error executing query." ));
288  }
289 
290  // ----------------------------------------------------------------------
291  // return the results of the query
292  // ----------------------------------------------------------------------
293 
295 
296  while (query.next())
297  {
298 
299  DTC::VideoSource *pVideoSource = pList->AddNewVideoSource();
300 
301  pVideoSource->setId ( query.value(0).toInt() );
302  pVideoSource->setSourceName ( query.value(1).toString() );
303  pVideoSource->setGrabber ( query.value(2).toString() );
304  pVideoSource->setUserId ( query.value(3).toString() );
305  pVideoSource->setFreqTable ( query.value(4).toString() );
306  pVideoSource->setLineupId ( query.value(5).toString() );
307  pVideoSource->setPassword ( query.value(6).toString() );
308  pVideoSource->setUseEIT ( query.value(7).toBool() );
309  pVideoSource->setConfigPath ( query.value(8).toString() );
310  pVideoSource->setNITId ( query.value(9).toInt() );
311  }
312 
313  pList->setAsOf ( MythDate::current() );
314  pList->setVersion ( MYTH_BINARY_VERSION );
315  pList->setProtoVer ( MYTH_PROTO_VERSION );
316 
317  return pList;
318 }
319 
321 //
323 
325 {
326  MSqlQuery query(MSqlQuery::InitCon());
327 
328  if (!query.isConnected())
329  throw( QString("Database not open while trying to list "
330  "Video Sources."));
331 
332  query.prepare("SELECT name, xmltvgrabber, userid, "
333  "freqtable, lineupid, password, useeit, configpath, "
334  "dvb_nit_id FROM videosource WHERE sourceid = :SOURCEID "
335  "ORDER BY sourceid" );
336  query.bindValue(":SOURCEID", nSourceID);
337 
338  if (!query.exec())
339  {
340  MythDB::DBError("MythAPI::GetVideoSource()", query);
341 
342  throw( QString( "Database Error executing query." ));
343  }
344 
345  // ----------------------------------------------------------------------
346  // return the results of the query
347  // ----------------------------------------------------------------------
348 
349  DTC::VideoSource *pVideoSource = new DTC::VideoSource();
350 
351  if (query.next())
352  {
353  pVideoSource->setId ( nSourceID );
354  pVideoSource->setSourceName ( query.value(0).toString() );
355  pVideoSource->setGrabber ( query.value(1).toString() );
356  pVideoSource->setUserId ( query.value(2).toString() );
357  pVideoSource->setFreqTable ( query.value(3).toString() );
358  pVideoSource->setLineupId ( query.value(4).toString() );
359  pVideoSource->setPassword ( query.value(5).toString() );
360  pVideoSource->setUseEIT ( query.value(6).toBool() );
361  pVideoSource->setConfigPath ( query.value(7).toString() );
362  pVideoSource->setNITId ( query.value(8).toInt() );
363  }
364 
365  return pVideoSource;
366 }
367 
369 //
371 
373  const QString &sSourceName,
374  const QString &sGrabber,
375  const QString &sUserId,
376  const QString &sFreqTable,
377  const QString &sLineupId,
378  const QString &sPassword,
379  bool bUseEIT,
380  const QString &sConfigPath,
381  int nNITId )
382 {
383  bool bResult = false;
384 
385  bResult = SourceUtil::UpdateSource(nSourceId, sSourceName, sGrabber, sUserId, sFreqTable,
386  sLineupId, sPassword, bUseEIT, sConfigPath,
387  nNITId);
388 
389  return bResult;
390 }
391 
393 //
395 
396 int Channel::AddVideoSource( const QString &sSourceName,
397  const QString &sGrabber,
398  const QString &sUserId,
399  const QString &sFreqTable,
400  const QString &sLineupId,
401  const QString &sPassword,
402  bool bUseEIT,
403  const QString &sConfigPath,
404  int nNITId )
405 {
406  int nResult = SourceUtil::CreateSource(sSourceName, sGrabber, sUserId, sFreqTable,
407  sLineupId, sPassword, bUseEIT, sConfigPath,
408  nNITId);
409 
410  return nResult;
411 }
412 
414 //
416 
418 {
419  bool bResult = false;
420 
421  bResult = SourceUtil::DeleteSource( nSourceID );
422 
423  return bResult;
424 }
425 
427 //
429 
430 DTC::LineupList* Channel::GetDDLineupList( const QString &sSource,
431  const QString &sUserId,
432  const QString &sPassword )
433 {
434  int source = 0;
435 
436  DTC::LineupList *pLineups = new DTC::LineupList();
437 
438  if (sSource.toLower() == "schedulesdirect1" ||
439  sSource.toLower() == "schedulesdirect" ||
440  sSource.isEmpty())
441  {
442  source = 1;
443  DataDirectProcessor ddp(source, sUserId, sPassword);
444  if (!ddp.GrabLineupsOnly())
445  {
446  throw( QString("Unable to grab lineups. Check info."));
447  }
448  const DDLineupList lineups = ddp.GetLineups();
449 
450  DDLineupList::const_iterator it;
451  for (it = lineups.begin(); it != lineups.end(); ++it)
452  {
453  DTC::Lineup *pLineup = pLineups->AddNewLineup();
454 
455  pLineup->setLineupId((*it).lineupid);
456  pLineup->setName((*it).name);
457  pLineup->setDisplayName((*it).displayname);
458  pLineup->setType((*it).type);
459  pLineup->setPostal((*it).postal);
460  pLineup->setDevice((*it).device);
461  }
462  }
463 
464  return pLineups;
465 }
466 
468 //
470 
472  const uint nCardId,
473  bool bWaitForFinish )
474 {
475  if ( nSourceId < 1 || nCardId < 1)
476  throw( QString("A source ID and card ID are both required."));
477 
478  int nResult = 0;
479 
480  QString cardtype = CardUtil::GetRawCardType(nCardId);
481 
482  if (!CardUtil::IsUnscanable(cardtype) &&
483  !CardUtil::IsEncoder(cardtype))
484  {
485  throw( QString("This device is incompatible with channel fetching.") );
486  }
487 
488  SourceUtil::UpdateChannelsFromListings(nSourceId, cardtype, bWaitForFinish);
489 
490  if (bWaitForFinish)
491  nResult = SourceUtil::GetChannelCount(nSourceId);
492 
493  return nResult;
494 }
495 
497 //
499 
501  int nStartIndex,
502  int nCount )
503 {
504  MSqlQuery query(MSqlQuery::InitCon());
505 
506  if (!query.isConnected())
507  throw( QString("Database not open while trying to list "
508  "Video Sources."));
509 
510  query.prepare("SELECT mplexid, sourceid, transportid, networkid, "
511  "frequency, inversion, symbolrate, fec, polarity, "
512  "modulation, bandwidth, lp_code_rate, transmission_mode, "
513  "guard_interval, visible, constellation, hierarchy, hp_code_rate, "
514  "mod_sys, rolloff, sistandard, serviceversion, updatetimestamp, "
515  "default_authority FROM dtv_multiplex WHERE sourceid = :SOURCEID "
516  "ORDER BY mplexid" );
517  query.bindValue(":SOURCEID", nSourceID);
518 
519  if (!query.exec())
520  {
521  MythDB::DBError("MythAPI::GetVideoMultiplexList()", query);
522 
523  throw( QString( "Database Error executing query." ));
524  }
525 
526  int muxCount = query.size();
527 
528  // ----------------------------------------------------------------------
529  // Build Response
530  // ----------------------------------------------------------------------
531 
532  DTC::VideoMultiplexList *pVideoMultiplexes = new DTC::VideoMultiplexList();
533 
534  nStartIndex = min( nStartIndex, muxCount );
535  nCount = (nCount > 0) ? min( nCount, muxCount ) : muxCount;
536  int nEndIndex = min((nStartIndex + nCount), muxCount );
537 
538  for( int n = nStartIndex; n < nEndIndex; n++)
539  {
540  if (query.seek(n))
541  {
542  DTC::VideoMultiplex *pVideoMultiplex = pVideoMultiplexes->AddNewVideoMultiplex();
543 
544  pVideoMultiplex->setMplexId( query.value(0).toInt() );
545  pVideoMultiplex->setSourceId( query.value(1).toInt() );
546  pVideoMultiplex->setTransportId( query.value(2).toInt() );
547  pVideoMultiplex->setNetworkId( query.value(3).toInt() );
548  pVideoMultiplex->setFrequency( query.value(4).toLongLong() );
549  pVideoMultiplex->setInversion( query.value(5).toString() );
550  pVideoMultiplex->setSymbolRate( query.value(6).toLongLong() );
551  pVideoMultiplex->setFEC( query.value(7).toString() );
552  pVideoMultiplex->setPolarity( query.value(8).toString() );
553  pVideoMultiplex->setModulation( query.value(9).toString() );
554  pVideoMultiplex->setBandwidth( query.value(10).toString() );
555  pVideoMultiplex->setLPCodeRate( query.value(11).toString() );
556  pVideoMultiplex->setTransmissionMode( query.value(12).toString() );
557  pVideoMultiplex->setGuardInterval( query.value(13).toString() );
558  pVideoMultiplex->setVisible( query.value(14).toBool() );
559  pVideoMultiplex->setConstellation( query.value(15).toString() );
560  pVideoMultiplex->setHierarchy( query.value(16).toString() );
561  pVideoMultiplex->setHPCodeRate( query.value(17).toString() );
562  pVideoMultiplex->setModulationSystem( query.value(18).toString() );
563  pVideoMultiplex->setRollOff( query.value(19).toString() );
564  pVideoMultiplex->setSIStandard( query.value(20).toString() );
565  pVideoMultiplex->setServiceVersion( query.value(21).toInt() );
566  pVideoMultiplex->setUpdateTimeStamp(
567  MythDate::as_utc(query.value(22).toDateTime()));
568  pVideoMultiplex->setDefaultAuthority( query.value(23).toString() );
569  }
570  }
571 
572  int curPage = 0, totalPages = 0;
573  if (nCount == 0)
574  totalPages = 1;
575  else
576  totalPages = (int)ceil((float)muxCount / nCount);
577 
578  if (totalPages == 1)
579  curPage = 1;
580  else
581  {
582  curPage = (int)ceil((float)nStartIndex / nCount) + 1;
583  }
584 
585  pVideoMultiplexes->setStartIndex ( nStartIndex );
586  pVideoMultiplexes->setCount ( nCount );
587  pVideoMultiplexes->setCurrentPage ( curPage );
588  pVideoMultiplexes->setTotalPages ( totalPages );
589  pVideoMultiplexes->setTotalAvailable( muxCount );
590  pVideoMultiplexes->setAsOf ( MythDate::current() );
591  pVideoMultiplexes->setVersion ( MYTH_BINARY_VERSION );
592  pVideoMultiplexes->setProtoVer ( MYTH_PROTO_VERSION );
593 
594  return pVideoMultiplexes;
595 }
596 
598 {
599  MSqlQuery query(MSqlQuery::InitCon());
600 
601  if (!query.isConnected())
602  throw( QString("Database not open while trying to list "
603  "Video Multiplex."));
604 
605  query.prepare("SELECT sourceid, transportid, networkid, "
606  "frequency, inversion, symbolrate, fec, polarity, "
607  "modulation, bandwidth, lp_code_rate, transmission_mode, "
608  "guard_interval, visible, constellation, hierarchy, hp_code_rate, "
609  "mod_sys, rolloff, sistandard, serviceversion, updatetimestamp, "
610  "default_authority FROM dtv_multiplex WHERE mplexid = :MPLEXID "
611  "ORDER BY mplexid" );
612  query.bindValue(":MPLEXID", nMplexID);
613 
614  if (!query.exec())
615  {
616  MythDB::DBError("MythAPI::GetVideoMultiplex()", query);
617 
618  throw( QString( "Database Error executing query." ));
619  }
620 
621  DTC::VideoMultiplex *pVideoMultiplex = new DTC::VideoMultiplex();
622 
623  if (query.next())
624  {
625  pVideoMultiplex->setMplexId( nMplexID );
626  pVideoMultiplex->setSourceId( query.value(0).toInt() );
627  pVideoMultiplex->setTransportId( query.value(1).toInt() );
628  pVideoMultiplex->setNetworkId( query.value(2).toInt() );
629  pVideoMultiplex->setFrequency( query.value(3).toLongLong() );
630  pVideoMultiplex->setInversion( query.value(4).toString() );
631  pVideoMultiplex->setSymbolRate( query.value(5).toLongLong() );
632  pVideoMultiplex->setFEC( query.value(6).toString() );
633  pVideoMultiplex->setPolarity( query.value(7).toString() );
634  pVideoMultiplex->setModulation( query.value(8).toString() );
635  pVideoMultiplex->setBandwidth( query.value(9).toString() );
636  pVideoMultiplex->setLPCodeRate( query.value(10).toString() );
637  pVideoMultiplex->setTransmissionMode( query.value(11).toString() );
638  pVideoMultiplex->setGuardInterval( query.value(12).toString() );
639  pVideoMultiplex->setVisible( query.value(13).toBool() );
640  pVideoMultiplex->setConstellation( query.value(14).toString() );
641  pVideoMultiplex->setHierarchy( query.value(15).toString() );
642  pVideoMultiplex->setHPCodeRate( query.value(16).toString() );
643  pVideoMultiplex->setModulationSystem( query.value(17).toString() );
644  pVideoMultiplex->setRollOff( query.value(18).toString() );
645  pVideoMultiplex->setSIStandard( query.value(19).toString() );
646  pVideoMultiplex->setServiceVersion( query.value(20).toInt() );
647  pVideoMultiplex->setUpdateTimeStamp(
648  MythDate::as_utc(query.value(21).toDateTime()));
649  pVideoMultiplex->setDefaultAuthority( query.value(22).toString() );
650  }
651 
652  return pVideoMultiplex;
653 }
654 
656 //
658 
660 {
661  MSqlQuery query(MSqlQuery::InitCon());
662 
663  if (!query.isConnected())
664  throw( QString("Database not open while trying to get source name."));
665 
666  query.prepare("SELECT name FROM videosource WHERE sourceid = :SOURCEID ");
667  query.bindValue(":SOURCEID", SourceID);
668 
669  if (!query.exec())
670  {
671  MythDB::DBError("MythAPI::GetXMLTVIdList()", query);
672 
673  throw( QString( "Database Error executing query." ));
674  }
675 
676  QStringList idList;
677 
678  if (query.next())
679  {
680  QString sourceName = query.value(0).toString();
681 
682  QString xmltvFile = GetConfDir() + '/' + sourceName + ".xmltv";
683 
684  if (QFile::exists(xmltvFile))
685  {
686  QFile file(xmltvFile);
687  if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
688  return idList;
689 
690  while (!file.atEnd())
691  {
692  QByteArray line = file.readLine();
693 
694  if (line.startsWith("channel="))
695  {
696  QString id = line.mid(8, -1).trimmed();
697  idList.append(id);
698  }
699  }
700 
701  idList.sort();
702  }
703  }
704  else
705  throw(QString("SourceID (%1) not found").arg(SourceID));
706 
707  return idList;
708 }