MythTV  0.28pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
channel.cpp
Go to the documentation of this file.
1 // Program Name: channel.cpp
3 // Created : Apr. 8, 2011
4 //
5 // Copyright (c) 2011 Robert McNamara <rmcnamara@mythtv.org>
6 // Copyright (c) 2013 MythTV Developers
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program. If not, see <http://www.gnu.org/licenses/>.
24 //
26 
27 #include <QList>
28 
29 #include <math.h>
30 
31 #include "channel.h"
32 
33 #include "compat.h"
34 #include "mythdbcon.h"
35 #include "mythdirs.h"
36 #include "mythversion.h"
37 #include "mythcorecontext.h"
38 #include "channelutil.h"
39 #include "sourceutil.h"
40 #include "cardutil.h"
41 #include "datadirect.h"
42 #include "mythdate.h"
43 
44 #include "serviceUtil.h"
45 
47 //
49 
51  uint nStartIndex,
52  uint nCount )
53 {
54  vector<uint> chanList;
55 
56  chanList = ChannelUtil::GetChanIDs(nSourceID);
57 
58  // ----------------------------------------------------------------------
59  // Build Response
60  // ----------------------------------------------------------------------
61 
62  DTC::ChannelInfoList *pChannelInfos = new DTC::ChannelInfoList();
63 
64  nStartIndex = min( nStartIndex, (uint)chanList.size() );
65  nCount = (nCount > 0) ? min( nCount, (uint)chanList.size() ) : chanList.size();
66  int nEndIndex = min((nStartIndex + nCount), (uint)chanList.size() );
67 
68  for( int n = nStartIndex; n < nEndIndex; n++)
69  {
70  DTC::ChannelInfo *pChannelInfo = pChannelInfos->AddNewChannelInfo();
71 
72  uint chanid = chanList.at(n);
73 
74  if (!FillChannelInfo(pChannelInfo, chanid, true))
75  throw( QString("Channel ID appears invalid."));
76  }
77 
78  int curPage = 0, totalPages = 0;
79  if (nCount == 0)
80  totalPages = 1;
81  else
82  totalPages = (int)ceil((float)chanList.size() / nCount);
83 
84  if (totalPages == 1)
85  curPage = 1;
86  else
87  {
88  curPage = (int)ceil((float)nStartIndex / nCount) + 1;
89  }
90 
91  pChannelInfos->setStartIndex ( nStartIndex );
92  pChannelInfos->setCount ( nCount );
93  pChannelInfos->setCurrentPage ( curPage );
94  pChannelInfos->setTotalPages ( totalPages );
95  pChannelInfos->setTotalAvailable( chanList.size() );
96  pChannelInfos->setAsOf ( MythDate::current() );
97  pChannelInfos->setVersion ( MYTH_BINARY_VERSION );
98  pChannelInfos->setProtoVer ( MYTH_PROTO_VERSION );
99 
100  return pChannelInfos;
101 }
102 
104 //
106 
108 {
109  if (nChanID <= 0)
110  throw( QString("Channel ID appears invalid."));
111 
112  DTC::ChannelInfo *pChannelInfo = new DTC::ChannelInfo();
113 
114  if (!FillChannelInfo(pChannelInfo, nChanID, true))
115  {
116  // throw causes a crash on linux and we can't know in advance
117  // that a channel id from an old recording rule is invalid
118  //throw( QString("Channel ID appears invalid."));
119  }
120 
121  return pChannelInfo;
122 }
123 
125  uint SourceID,
126  uint ChannelID,
127  const QString &CallSign,
128  const QString &ChannelName,
129  const QString &ChannelNumber,
130  uint ServiceID,
131  uint ATSCMajorChannel,
132  uint ATSCMinorChannel,
133  bool UseEIT,
134  bool visible,
135  const QString &FrequencyID,
136  const QString &Icon,
137  const QString &Format,
138  const QString &XMLTVID,
139  const QString &DefaultAuthority )
140 {
141  bool bResult = false;
142 
143  bResult = ChannelUtil::UpdateChannel( MplexID, SourceID, ChannelID,
144  CallSign, ChannelName, ChannelNumber,
145  ServiceID, ATSCMajorChannel, ATSCMinorChannel,
146  UseEIT, !visible, false, FrequencyID,
147  Icon, Format, XMLTVID, DefaultAuthority );
148 
149  return bResult;
150 }
151 
153  uint SourceID,
154  uint ChannelID,
155  const QString &CallSign,
156  const QString &ChannelName,
157  const QString &ChannelNumber,
158  uint ServiceID,
159  uint ATSCMajorChannel,
160  uint ATSCMinorChannel,
161  bool UseEIT,
162  bool visible,
163  const QString &FrequencyID,
164  const QString &Icon,
165  const QString &Format,
166  const QString &XMLTVID,
167  const QString &DefaultAuthority )
168 {
169  bool bResult = false;
170 
171  bResult = ChannelUtil::CreateChannel( MplexID, SourceID, ChannelID,
172  CallSign, ChannelName, ChannelNumber,
173  ServiceID, ATSCMajorChannel, ATSCMinorChannel,
174  UseEIT, !visible, false, FrequencyID,
175  Icon, Format, XMLTVID, DefaultAuthority );
176 
177  return bResult;
178 }
179 
180 bool Channel::RemoveDBChannel( uint nChannelID )
181 {
182  bool bResult = false;
183 
184  bResult = ChannelUtil::DeleteChannel( nChannelID );
185 
186  return bResult;
187 }
188 
190 //
192 
194 {
195  MSqlQuery query(MSqlQuery::InitCon());
196 
197  if (!query.isConnected())
198  throw( QString("Database not open while trying to list "
199  "Video Sources."));
200 
201  query.prepare("SELECT sourceid, name, xmltvgrabber, userid, "
202  "freqtable, lineupid, password, useeit, configpath, "
203  "dvb_nit_id FROM videosource "
204  "ORDER BY sourceid" );
205 
206  if (!query.exec())
207  {
208  MythDB::DBError("MythAPI::GetVideoSourceList()", query);
209 
210  throw( QString( "Database Error executing query." ));
211  }
212 
213  // ----------------------------------------------------------------------
214  // return the results of the query
215  // ----------------------------------------------------------------------
216 
218 
219  while (query.next())
220  {
221 
222  DTC::VideoSource *pVideoSource = pList->AddNewVideoSource();
223 
224  pVideoSource->setId ( query.value(0).toInt() );
225  pVideoSource->setSourceName ( query.value(1).toString() );
226  pVideoSource->setGrabber ( query.value(2).toString() );
227  pVideoSource->setUserId ( query.value(3).toString() );
228  pVideoSource->setFreqTable ( query.value(4).toString() );
229  pVideoSource->setLineupId ( query.value(5).toString() );
230  pVideoSource->setPassword ( query.value(6).toString() );
231  pVideoSource->setUseEIT ( query.value(7).toBool() );
232  pVideoSource->setConfigPath ( query.value(8).toString() );
233  pVideoSource->setNITId ( query.value(9).toInt() );
234  }
235 
236  pList->setAsOf ( MythDate::current() );
237  pList->setVersion ( MYTH_BINARY_VERSION );
238  pList->setProtoVer ( MYTH_PROTO_VERSION );
239 
240  return pList;
241 }
242 
244 //
246 
248 {
249  MSqlQuery query(MSqlQuery::InitCon());
250 
251  if (!query.isConnected())
252  throw( QString("Database not open while trying to list "
253  "Video Sources."));
254 
255  query.prepare("SELECT name, xmltvgrabber, userid, "
256  "freqtable, lineupid, password, useeit, configpath, "
257  "dvb_nit_id FROM videosource WHERE sourceid = :SOURCEID "
258  "ORDER BY sourceid" );
259  query.bindValue(":SOURCEID", nSourceID);
260 
261  if (!query.exec())
262  {
263  MythDB::DBError("MythAPI::GetVideoSource()", query);
264 
265  throw( QString( "Database Error executing query." ));
266  }
267 
268  // ----------------------------------------------------------------------
269  // return the results of the query
270  // ----------------------------------------------------------------------
271 
272  DTC::VideoSource *pVideoSource = new DTC::VideoSource();
273 
274  if (query.next())
275  {
276  pVideoSource->setId ( nSourceID );
277  pVideoSource->setSourceName ( query.value(0).toString() );
278  pVideoSource->setGrabber ( query.value(1).toString() );
279  pVideoSource->setUserId ( query.value(2).toString() );
280  pVideoSource->setFreqTable ( query.value(3).toString() );
281  pVideoSource->setLineupId ( query.value(4).toString() );
282  pVideoSource->setPassword ( query.value(5).toString() );
283  pVideoSource->setUseEIT ( query.value(6).toBool() );
284  pVideoSource->setConfigPath ( query.value(7).toString() );
285  pVideoSource->setNITId ( query.value(8).toInt() );
286  }
287 
288  return pVideoSource;
289 }
290 
292 //
294 
296  const QString &sSourceName,
297  const QString &sGrabber,
298  const QString &sUserId,
299  const QString &sFreqTable,
300  const QString &sLineupId,
301  const QString &sPassword,
302  bool bUseEIT,
303  const QString &sConfigPath,
304  int nNITId )
305 {
306  bool bResult = false;
307 
308  bResult = SourceUtil::UpdateSource(nSourceId, sSourceName, sGrabber, sUserId, sFreqTable,
309  sLineupId, sPassword, bUseEIT, sConfigPath,
310  nNITId);
311 
312  return bResult;
313 }
314 
316 //
318 
319 int Channel::AddVideoSource( const QString &sSourceName,
320  const QString &sGrabber,
321  const QString &sUserId,
322  const QString &sFreqTable,
323  const QString &sLineupId,
324  const QString &sPassword,
325  bool bUseEIT,
326  const QString &sConfigPath,
327  int nNITId )
328 {
329  int nResult = SourceUtil::CreateSource(sSourceName, sGrabber, sUserId, sFreqTable,
330  sLineupId, sPassword, bUseEIT, sConfigPath,
331  nNITId);
332 
333  return nResult;
334 }
335 
337 //
339 
341 {
342  bool bResult = false;
343 
344  bResult = SourceUtil::DeleteSource( nSourceID );
345 
346  return bResult;
347 }
348 
350 //
352 
353 DTC::LineupList* Channel::GetDDLineupList( const QString &sSource,
354  const QString &sUserId,
355  const QString &sPassword )
356 {
357  int source = 0;
358 
359  DTC::LineupList *pLineups = new DTC::LineupList();
360 
361  if (sSource.toLower() == "schedulesdirect1" ||
362  sSource.toLower() == "schedulesdirect" ||
363  sSource.isEmpty())
364  {
365  source = 1;
366  DataDirectProcessor ddp(source, sUserId, sPassword);
367  if (!ddp.GrabLineupsOnly())
368  {
369  throw( QString("Unable to grab lineups. Check info."));
370  }
371  const DDLineupList lineups = ddp.GetLineups();
372 
373  DDLineupList::const_iterator it;
374  for (it = lineups.begin(); it != lineups.end(); ++it)
375  {
376  DTC::Lineup *pLineup = pLineups->AddNewLineup();
377 
378  pLineup->setLineupId((*it).lineupid);
379  pLineup->setName((*it).name);
380  pLineup->setDisplayName((*it).displayname);
381  pLineup->setType((*it).type);
382  pLineup->setPostal((*it).postal);
383  pLineup->setDevice((*it).device);
384  }
385  }
386 
387  return pLineups;
388 }
389 
391 //
393 
395  const uint nCardId,
396  bool bWaitForFinish )
397 {
398  if ( nSourceId < 1 || nCardId < 1)
399  throw( QString("A source ID and card ID are both required."));
400 
401  int nResult = 0;
402 
403  QString cardtype = CardUtil::GetRawCardType(nCardId);
404 
405  if (!CardUtil::IsUnscanable(cardtype) &&
406  !CardUtil::IsEncoder(cardtype))
407  {
408  throw( QString("This device is incompatible with channel fetching.") );
409  }
410 
411  SourceUtil::UpdateChannelsFromListings(nSourceId, cardtype, bWaitForFinish);
412 
413  if (bWaitForFinish)
414  nResult = SourceUtil::GetChannelCount(nSourceId);
415 
416  return nResult;
417 }
418 
420 //
422 
424  uint nStartIndex,
425  uint nCount )
426 {
427  MSqlQuery query(MSqlQuery::InitCon());
428 
429  if (!query.isConnected())
430  throw( QString("Database not open while trying to list "
431  "Video Sources."));
432 
433  query.prepare("SELECT mplexid, sourceid, transportid, networkid, "
434  "frequency, inversion, symbolrate, fec, polarity, "
435  "modulation, bandwidth, lp_code_rate, transmission_mode, "
436  "guard_interval, visible, constellation, hierarchy, hp_code_rate, "
437  "mod_sys, rolloff, sistandard, serviceversion, updatetimestamp, "
438  "default_authority FROM dtv_multiplex WHERE sourceid = :SOURCEID "
439  "ORDER BY mplexid" );
440  query.bindValue(":SOURCEID", nSourceID);
441 
442  if (!query.exec())
443  {
444  MythDB::DBError("MythAPI::GetVideoMultiplexList()", query);
445 
446  throw( QString( "Database Error executing query." ));
447  }
448 
449  uint muxCount = (uint)query.size();
450 
451  // ----------------------------------------------------------------------
452  // Build Response
453  // ----------------------------------------------------------------------
454 
455  DTC::VideoMultiplexList *pVideoMultiplexes = new DTC::VideoMultiplexList();
456 
457  nStartIndex = min( nStartIndex, muxCount );
458  nCount = (nCount > 0) ? min( nCount, muxCount ) : muxCount;
459  int nEndIndex = min((nStartIndex + nCount), muxCount );
460 
461  for( int n = nStartIndex; n < nEndIndex; n++)
462  {
463  if (query.seek(n))
464  {
465  DTC::VideoMultiplex *pVideoMultiplex = pVideoMultiplexes->AddNewVideoMultiplex();
466 
467  pVideoMultiplex->setMplexId( query.value(0).toInt() );
468  pVideoMultiplex->setSourceId( query.value(1).toInt() );
469  pVideoMultiplex->setTransportId( query.value(2).toInt() );
470  pVideoMultiplex->setNetworkId( query.value(3).toInt() );
471  pVideoMultiplex->setFrequency( query.value(4).toLongLong() );
472  pVideoMultiplex->setInversion( query.value(5).toString() );
473  pVideoMultiplex->setSymbolRate( query.value(6).toLongLong() );
474  pVideoMultiplex->setFEC( query.value(7).toString() );
475  pVideoMultiplex->setPolarity( query.value(8).toString() );
476  pVideoMultiplex->setModulation( query.value(9).toString() );
477  pVideoMultiplex->setBandwidth( query.value(10).toString() );
478  pVideoMultiplex->setLPCodeRate( query.value(11).toString() );
479  pVideoMultiplex->setTransmissionMode( query.value(12).toString() );
480  pVideoMultiplex->setGuardInterval( query.value(13).toString() );
481  pVideoMultiplex->setVisible( query.value(14).toBool() );
482  pVideoMultiplex->setConstellation( query.value(15).toString() );
483  pVideoMultiplex->setHierarchy( query.value(16).toString() );
484  pVideoMultiplex->setHPCodeRate( query.value(17).toString() );
485  pVideoMultiplex->setModulationSystem( query.value(18).toString() );
486  pVideoMultiplex->setRollOff( query.value(19).toString() );
487  pVideoMultiplex->setSIStandard( query.value(20).toString() );
488  pVideoMultiplex->setServiceVersion( query.value(21).toInt() );
489  pVideoMultiplex->setUpdateTimeStamp(
490  MythDate::as_utc(query.value(22).toDateTime()));
491  pVideoMultiplex->setDefaultAuthority( query.value(23).toString() );
492  }
493  }
494 
495  int curPage = 0, totalPages = 0;
496  if (nCount == 0)
497  totalPages = 1;
498  else
499  totalPages = (int)ceil((float)muxCount / nCount);
500 
501  if (totalPages == 1)
502  curPage = 1;
503  else
504  {
505  curPage = (int)ceil((float)nStartIndex / nCount) + 1;
506  }
507 
508  pVideoMultiplexes->setStartIndex ( nStartIndex );
509  pVideoMultiplexes->setCount ( nCount );
510  pVideoMultiplexes->setCurrentPage ( curPage );
511  pVideoMultiplexes->setTotalPages ( totalPages );
512  pVideoMultiplexes->setTotalAvailable( muxCount );
513  pVideoMultiplexes->setAsOf ( MythDate::current() );
514  pVideoMultiplexes->setVersion ( MYTH_BINARY_VERSION );
515  pVideoMultiplexes->setProtoVer ( MYTH_PROTO_VERSION );
516 
517  return pVideoMultiplexes;
518 }
519 
521 {
522  MSqlQuery query(MSqlQuery::InitCon());
523 
524  if (!query.isConnected())
525  throw( QString("Database not open while trying to list "
526  "Video Multiplex."));
527 
528  query.prepare("SELECT sourceid, transportid, networkid, "
529  "frequency, inversion, symbolrate, fec, polarity, "
530  "modulation, bandwidth, lp_code_rate, transmission_mode, "
531  "guard_interval, visible, constellation, hierarchy, hp_code_rate, "
532  "mod_sys, rolloff, sistandard, serviceversion, updatetimestamp, "
533  "default_authority FROM dtv_multiplex WHERE mplexid = :MPLEXID "
534  "ORDER BY mplexid" );
535  query.bindValue(":MPLEXID", nMplexID);
536 
537  if (!query.exec())
538  {
539  MythDB::DBError("MythAPI::GetVideoMultiplex()", query);
540 
541  throw( QString( "Database Error executing query." ));
542  }
543 
544  DTC::VideoMultiplex *pVideoMultiplex = new DTC::VideoMultiplex();
545 
546  if (query.next())
547  {
548  pVideoMultiplex->setMplexId( nMplexID );
549  pVideoMultiplex->setSourceId( query.value(0).toInt() );
550  pVideoMultiplex->setTransportId( query.value(1).toInt() );
551  pVideoMultiplex->setNetworkId( query.value(2).toInt() );
552  pVideoMultiplex->setFrequency( query.value(3).toLongLong() );
553  pVideoMultiplex->setInversion( query.value(4).toString() );
554  pVideoMultiplex->setSymbolRate( query.value(5).toLongLong() );
555  pVideoMultiplex->setFEC( query.value(6).toString() );
556  pVideoMultiplex->setPolarity( query.value(7).toString() );
557  pVideoMultiplex->setModulation( query.value(8).toString() );
558  pVideoMultiplex->setBandwidth( query.value(9).toString() );
559  pVideoMultiplex->setLPCodeRate( query.value(10).toString() );
560  pVideoMultiplex->setTransmissionMode( query.value(11).toString() );
561  pVideoMultiplex->setGuardInterval( query.value(12).toString() );
562  pVideoMultiplex->setVisible( query.value(13).toBool() );
563  pVideoMultiplex->setConstellation( query.value(14).toString() );
564  pVideoMultiplex->setHierarchy( query.value(15).toString() );
565  pVideoMultiplex->setHPCodeRate( query.value(16).toString() );
566  pVideoMultiplex->setModulationSystem( query.value(17).toString() );
567  pVideoMultiplex->setRollOff( query.value(18).toString() );
568  pVideoMultiplex->setSIStandard( query.value(19).toString() );
569  pVideoMultiplex->setServiceVersion( query.value(20).toInt() );
570  pVideoMultiplex->setUpdateTimeStamp(
571  MythDate::as_utc(query.value(21).toDateTime()));
572  pVideoMultiplex->setDefaultAuthority( query.value(22).toString() );
573  }
574 
575  return pVideoMultiplex;
576 }
577 
579 //
581 
583 {
584  MSqlQuery query(MSqlQuery::InitCon());
585 
586  if (!query.isConnected())
587  throw( QString("Database not open while trying to get source name."));
588 
589  query.prepare("SELECT name FROM videosource WHERE sourceid = :SOURCEID ");
590  query.bindValue(":SOURCEID", SourceID);
591 
592  if (!query.exec())
593  {
594  MythDB::DBError("MythAPI::GetXMLTVIdList()", query);
595 
596  throw( QString( "Database Error executing query." ));
597  }
598 
599  QStringList idList;
600 
601  if (query.next())
602  {
603  QString sourceName = query.value(0).toString();
604 
605  QString xmltvFile = GetConfDir() + '/' + sourceName + ".xmltv";
606 
607  if (QFile::exists(xmltvFile))
608  {
609  QFile file(xmltvFile);
610  if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
611  return idList;
612 
613  while (!file.atEnd())
614  {
615  QByteArray line = file.readLine();
616 
617  if (line.startsWith("channel="))
618  {
619  QString id = line.mid(8, -1).trimmed();
620  idList.append(id);
621  }
622  }
623 
624  idList.sort();
625  }
626  }
627  else
628  throw(QString("SourceID (%1) not found").arg(SourceID));
629 
630  return idList;
631 }