MythTV  master
myth.cpp
Go to the documentation of this file.
1 // Program Name: myth.cpp
3 // Created : Jan. 19, 2010
4 //
5 // Copyright (c) 2010 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 // Qt
27 #include <QDir>
28 #include <QFileInfo>
29 #include <QCryptographicHash>
30 #include <QHostAddress>
31 #include <QUdpSocket>
32 
33 // MythTV
34 #include "libmythbase/dbutil.h"
38 #include "libmythbase/mythdate.h"
39 #include "libmythbase/mythdbcon.h"
42 #include "libmythbase/mythversion.h"
44 #include "libmythbase/version.h"
45 
46 // MythBackend
47 #include "backendcontext.h"
48 #include "myth.h"
49 #include "scheduler.h"
50 #include "serviceUtil.h"
51 
53 //
55 
57 {
58  QString sSecurityPin = gCoreContext->GetSetting( "SecurityPin", "");
59 
60  if ( sSecurityPin.isEmpty() )
61  throw( QString( "No Security Pin assigned. Run mythtv-setup to set one." ));
62  //SB: UPnPResult_HumanInterventionRequired,
63 
64  if ((sSecurityPin != "0000" ) && ( sPin != sSecurityPin ))
65  throw( QString( "Not Authorized" ));
66  //SB: UPnPResult_ActionNotAuthorized );
67 
68  DatabaseParams params = GetMythDB()->GetDatabaseParams();
69 
70  // ----------------------------------------------------------------------
71  // Check for DBHostName of "localhost" and change to public name or IP
72  // ----------------------------------------------------------------------
73 
74  QString sServerIP = gCoreContext->GetBackendServerIP();
75  //QString sPeerIP = pRequest->GetPeerAddress();
76 
77  if ((params.m_dbHostName.compare("localhost",Qt::CaseInsensitive)==0
78  || params.m_dbHostName == "127.0.0.1"
79  || params.m_dbHostName == "::1")
80  && !sServerIP.isEmpty()) // &&
81  //(sServerIP != sPeerIP ))
82  {
83  params.m_dbHostName = sServerIP;
84  }
85 
86  // If dbHostName is an IPV6 address with scope,
87  // remove the scope. Unescaped % signs are an
88  // xml violation
89  QString dbHostName(params.m_dbHostName);
90  QHostAddress addr;
91  if (addr.setAddress(dbHostName))
92  {
93  addr.setScopeId(QString());
94  dbHostName = addr.toString();
95  }
96  // ----------------------------------------------------------------------
97  // Create and populate a ConnectionInfo object
98  // ----------------------------------------------------------------------
99 
100  auto *pInfo = new DTC::ConnectionInfo();
101  DTC::DatabaseInfo *pDatabase = pInfo->Database();
102  DTC::WOLInfo *pWOL = pInfo->WOL();
103  DTC::VersionInfo *pVersion = pInfo->Version();
104 
105  pDatabase->setHost ( dbHostName );
106  pDatabase->setPing ( params.m_dbHostPing );
107  pDatabase->setPort ( params.m_dbPort );
108  pDatabase->setUserName ( params.m_dbUserName );
109  pDatabase->setPassword ( params.m_dbPassword );
110  pDatabase->setName ( params.m_dbName );
111  pDatabase->setType ( params.m_dbType );
112  pDatabase->setLocalEnabled ( params.m_localEnabled );
113  pDatabase->setLocalHostName( params.m_localHostName );
114 
115  pWOL->setEnabled ( params.m_wolEnabled );
116  pWOL->setReconnect ( params.m_wolReconnect.count() );
117  pWOL->setRetry ( params.m_wolRetry );
118  pWOL->setCommand ( params.m_wolCommand );
119 
120  pVersion->setVersion ( MYTH_SOURCE_VERSION );
121  pVersion->setBranch ( MYTH_SOURCE_PATH );
122  pVersion->setProtocol ( MYTH_PROTO_VERSION );
123  pVersion->setBinary ( MYTH_BINARY_VERSION );
124  pVersion->setSchema ( MYTH_DATABASE_VERSION );
125 
126  // ----------------------------------------------------------------------
127  // Return the pointer... caller is responsible to delete it!!!
128  // ----------------------------------------------------------------------
129 
130  return pInfo;
131 }
132 
134 //
136 
138 {
139  if (!gCoreContext)
140  throw( QString( "No MythCoreContext in GetHostName." ));
141 
142  return gCoreContext->GetHostName();
143 }
145 //
147 
148 QStringList Myth::GetHosts( )
149 {
150  MSqlQuery query(MSqlQuery::InitCon());
151 
152  if (!query.isConnected())
153  throw( QString( "Database not open while trying to load list of hosts" ));
154 
155  query.prepare(
156  "SELECT DISTINCTROW hostname "
157  "FROM settings "
158  "WHERE (not isNull( hostname ))");
159 
160  if (!query.exec())
161  {
162  MythDB::DBError("MythAPI::GetHosts()", query);
163 
164  throw( QString( "Database Error executing query." ));
165  }
166 
167  // ----------------------------------------------------------------------
168  // return the results of the query
169  // ----------------------------------------------------------------------
170 
171  QStringList oList;
172 
173  while (query.next())
174  oList.append( query.value(0).toString() );
175 
176  return oList;
177 }
178 
180 //
182 
183 QStringList Myth::GetKeys()
184 {
185  MSqlQuery query(MSqlQuery::InitCon());
186 
187  if (!query.isConnected())
188  throw( QString("Database not open while trying to load settings"));
189 
190  query.prepare("SELECT DISTINCTROW value FROM settings;" );
191 
192  if (!query.exec())
193  {
194  MythDB::DBError("MythAPI::GetKeys()", query);
195 
196  throw( QString( "Database Error executing query." ));
197  }
198 
199  // ----------------------------------------------------------------------
200  // return the results of the query
201  // ----------------------------------------------------------------------
202 
203  QStringList oResults;
204 
205  //pResults->setObjectName( "KeyList" );
206 
207  while (query.next())
208  oResults.append( query.value(0).toString() );
209 
210  return oResults;
211 }
212 
214 //
216 
218  const QString &sHostName )
219 {
220  MSqlQuery query(MSqlQuery::InitCon());
221 
222  if (!query.isConnected())
223  throw( QString("Database not open while trying to list "
224  "Storage Group Dirs"));
225 
226  if (!sGroupName.isEmpty() && !sHostName.isEmpty())
227  {
228  query.prepare("SELECT id, groupname, hostname, dirname "
229  "FROM storagegroup "
230  "WHERE groupname = :GROUP AND hostname = :HOST "
231  "ORDER BY groupname, hostname, dirname" );
232  query.bindValue(":HOST", sHostName);
233  query.bindValue(":GROUP", sGroupName);
234  }
235  else if (!sHostName.isEmpty())
236  {
237  query.prepare("SELECT id, groupname, hostname, dirname "
238  "FROM storagegroup "
239  "WHERE hostname = :HOST "
240  "ORDER BY groupname, hostname, dirname" );
241  query.bindValue(":HOST", sHostName);
242  }
243  else if (!sGroupName.isEmpty())
244  {
245  query.prepare("SELECT id, groupname, hostname, dirname "
246  "FROM storagegroup "
247  "WHERE groupname = :GROUP "
248  "ORDER BY groupname, hostname, dirname" );
249  query.bindValue(":GROUP", sGroupName);
250  }
251  else
252  {
253  query.prepare("SELECT id, groupname, hostname, dirname "
254  "FROM storagegroup "
255  "ORDER BY groupname, hostname, dirname" );
256  }
257 
258  if (!query.exec())
259  {
260  MythDB::DBError("MythAPI::GetStorageGroupDirs()", query);
261 
262  throw( QString( "Database Error executing query." ));
263  }
264 
265  // ----------------------------------------------------------------------
266  // return the results of the query plus R/W and size information
267  // ----------------------------------------------------------------------
268 
269  auto* pList = new DTC::StorageGroupDirList();
270 
271  while (query.next())
272  {
273  DTC::StorageGroupDir *pStorageGroupDir = pList->AddNewStorageGroupDir();
274  QFileInfo fi(query.value(3).toString());
275  int64_t free = 0;
276  int64_t total = 0;
277  int64_t used = 0;
278 
279  free = getDiskSpace(query.value(3).toString(), total, used);
280 
281  pStorageGroupDir->setId ( query.value(0).toInt() );
282  pStorageGroupDir->setGroupName ( query.value(1).toString() );
283  pStorageGroupDir->setHostName ( query.value(2).toString() );
284  pStorageGroupDir->setDirName ( query.value(3).toString() );
285  pStorageGroupDir->setDirRead ( fi.isReadable() );
286  pStorageGroupDir->setDirWrite ( fi.isWritable() );
287  pStorageGroupDir->setKiBFree ( free );
288  }
289 
290  return pList;
291 }
292 
294 //
296 
297 bool Myth::AddStorageGroupDir( const QString &sGroupName,
298  const QString &sDirName,
299  const QString &sHostName )
300 {
301  MSqlQuery query(MSqlQuery::InitCon());
302 
303  if (!query.isConnected())
304  throw( QString("Database not open while trying to add Storage Group "
305  "dir"));
306 
307  if (sGroupName.isEmpty())
308  throw ( QString( "Storage Group Required" ));
309 
310  if (sDirName.isEmpty())
311  throw ( QString( "Directory Name Required" ));
312 
313  if (sHostName.isEmpty())
314  throw ( QString( "HostName Required" ));
315 
316  query.prepare("SELECT COUNT(*) "
317  "FROM storagegroup "
318  "WHERE groupname = :GROUPNAME "
319  "AND dirname = :DIRNAME "
320  "AND hostname = :HOSTNAME;");
321  query.bindValue(":GROUPNAME", sGroupName );
322  query.bindValue(":DIRNAME" , sDirName );
323  query.bindValue(":HOSTNAME" , sHostName );
324  if (!query.exec())
325  {
326  MythDB::DBError("MythAPI::AddStorageGroupDir()", query);
327 
328  throw( QString( "Database Error executing query." ));
329  }
330 
331  if (query.next())
332  {
333  if (query.value(0).toInt() > 0)
334  return false;
335  }
336 
337  query.prepare("INSERT storagegroup "
338  "( groupname, dirname, hostname ) "
339  "VALUES "
340  "( :GROUPNAME, :DIRNAME, :HOSTNAME );");
341  query.bindValue(":GROUPNAME", sGroupName );
342  query.bindValue(":DIRNAME" , sDirName );
343  query.bindValue(":HOSTNAME" , sHostName );
344 
345  if (!query.exec())
346  {
347  MythDB::DBError("MythAPI::AddStorageGroupDir()", query);
348 
349  throw( QString( "Database Error executing query." ));
350  }
351 
352  return true;
353 }
354 
356 //
358 
359 bool Myth::RemoveStorageGroupDir( const QString &sGroupName,
360  const QString &sDirName,
361  const QString &sHostName )
362 {
363  MSqlQuery query(MSqlQuery::InitCon());
364 
365  if (!query.isConnected())
366  throw( QString("Database not open while trying to remove Storage "
367  "Group dir"));
368 
369  if (sGroupName.isEmpty())
370  throw ( QString( "Storage Group Required" ));
371 
372  if (sDirName.isEmpty())
373  throw ( QString( "Directory Name Required" ));
374 
375  if (sHostName.isEmpty())
376  throw ( QString( "HostName Required" ));
377 
378  query.prepare("DELETE "
379  "FROM storagegroup "
380  "WHERE groupname = :GROUPNAME "
381  "AND dirname = :DIRNAME "
382  "AND hostname = :HOSTNAME;");
383  query.bindValue(":GROUPNAME", sGroupName );
384  query.bindValue(":DIRNAME" , sDirName );
385  query.bindValue(":HOSTNAME" , sHostName );
386  if (!query.exec())
387  {
388  MythDB::DBError("MythAPI::AddStorageGroupDir()", query);
389 
390  throw( QString( "Database Error executing query." ));
391  }
392 
393  return true;
394 }
395 
397 //
399 
401 {
402  auto *pResults = new DTC::TimeZoneInfo();
403 
404  pResults->setTimeZoneID( MythTZ::getTimeZoneID() );
405  pResults->setUTCOffset( MythTZ::calc_utc_offset() );
406  pResults->setCurrentDateTime( MythDate::current(true) );
407 
408  return pResults;
409 }
410 
412 //
414 
415 QString Myth::GetFormatDate(const QDateTime &Date, bool ShortDate)
416 {
418  if (ShortDate)
420 
421  return MythDate::toString(Date, dateFormat);
422 }
423 
425 //
427 
428 QString Myth::GetFormatDateTime(const QDateTime &DateTime, bool ShortDate)
429 {
431  if (ShortDate)
433 
434  return MythDate::toString(DateTime, dateFormat);
435 }
436 
438 //
440 
441 QString Myth::GetFormatTime(const QDateTime &Time)
442 {
443  return MythDate::toString(Time, MythDate::kTime);
444 }
445 
447 //
449 
450 QDateTime Myth::ParseISODateString(const QString& DateTimeString)
451 {
452  QDateTime dateTime = QDateTime::fromString(DateTimeString, Qt::ISODate);
453 
454  if (!dateTime.isValid())
455  throw QString( "Unable to parse DateTimeString" );
456 
457  return dateTime;
458 }
459 
461 //
463 
464 DTC::LogMessageList *Myth::GetLogs( const QString &HostName,
465  const QString &Application,
466  int PID,
467  int TID,
468  const QString &Thread,
469  const QString &Filename,
470  int Line,
471  const QString &Function,
472  const QDateTime &FromTime,
473  const QDateTime &ToTime,
474  const QString &Level,
475  const QString &MsgContains )
476 {
477  auto *pList = new DTC::LogMessageList();
478 
479  MSqlQuery query(MSqlQuery::InitCon());
480 
481  // Get host name list
482  QString sql = "SELECT DISTINCT host FROM logging ORDER BY host ASC";
483  if (!query.exec(sql))
484  {
485  MythDB::DBError("Retrieving log host names", query);
486  delete pList;
487  throw( QString( "Database Error executing query." ));
488  }
489  while (query.next())
490  {
491  DTC::LabelValue *pLabelValue = pList->AddNewHostName();
492  QString availableHostName = query.value(0).toString();
493  pLabelValue->setValue ( availableHostName );
494  pLabelValue->setActive ( availableHostName == HostName );
495  pLabelValue->setSelected( availableHostName == HostName );
496  }
497  // Get application list
498  sql = "SELECT DISTINCT application FROM logging ORDER BY application ASC";
499  if (!query.exec(sql))
500  {
501  MythDB::DBError("Retrieving log applications", query);
502  delete pList;
503  throw( QString( "Database Error executing query." ));
504  }
505  while (query.next())
506  {
507  DTC::LabelValue *pLabelValue = pList->AddNewApplication();
508  QString availableApplication = query.value(0).toString();
509  pLabelValue->setValue ( availableApplication );
510  pLabelValue->setActive ( availableApplication == Application );
511  pLabelValue->setSelected( availableApplication == Application );
512  }
513 
514  if (!HostName.isEmpty() && !Application.isEmpty())
515  {
516  // Get log messages
517  sql = "SELECT host, application, pid, tid, thread, filename, "
518  " line, `function`, msgtime, level, message "
519  " FROM logging "
520  " WHERE host = COALESCE(:HOSTNAME, host) "
521  " AND application = COALESCE(:APPLICATION, application) "
522  " AND pid = COALESCE(:PID, pid) "
523  " AND tid = COALESCE(:TID, tid) "
524  " AND thread = COALESCE(:THREAD, thread) "
525  " AND filename = COALESCE(:FILENAME, filename) "
526  " AND line = COALESCE(:LINE, line) "
527  " AND `function` = COALESCE(:FUNCTION, `function`) "
528  " AND msgtime >= COALESCE(:FROMTIME, msgtime) "
529  " AND msgtime <= COALESCE(:TOTIME, msgtime) "
530  " AND level <= COALESCE(:LEVEL, level) "
531  ;
532  if (!MsgContains.isEmpty())
533  {
534  sql.append(" AND message LIKE :MSGCONTAINS ");
535  }
536  sql.append(" ORDER BY msgtime ASC;");
537 
538 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
539  QVariant ullNull = QVariant(QVariant::ULongLong);
540 #else
541  QVariant ullNull = QVariant(QMetaType(QMetaType::ULongLong));
542 #endif
543  query.prepare(sql);
544 
545  query.bindValue(":HOSTNAME", (HostName.isEmpty()) ? QString() : HostName);
546  query.bindValue(":APPLICATION", (Application.isEmpty()) ? QString() :
547  Application);
548  query.bindValue(":PID", ( PID == 0 ) ? ullNull : (qint64)PID);
549  query.bindValue(":TID", ( TID == 0 ) ? ullNull : (qint64)TID);
550  query.bindValue(":THREAD", (Thread.isEmpty()) ? QString() : Thread);
551  query.bindValue(":FILENAME", (Filename.isEmpty()) ? QString() : Filename);
552  query.bindValue(":LINE", ( Line == 0 ) ? ullNull : (qint64)Line);
553  query.bindValue(":FUNCTION", (Function.isEmpty()) ? QString() : Function);
554  query.bindValue(":FROMTIME", (FromTime.isValid()) ? FromTime : QDateTime());
555  query.bindValue(":TOTIME", (ToTime.isValid()) ? ToTime : QDateTime());
556  query.bindValue(":LEVEL", (Level.isEmpty()) ? ullNull :
557  (qint64)logLevelGet(Level));
558 
559  if (!MsgContains.isEmpty())
560  {
561  query.bindValue(":MSGCONTAINS", "%" + MsgContains + "%" );
562  }
563 
564  if (!query.exec())
565  {
566  MythDB::DBError("Retrieving log messages", query);
567  delete pList;
568  throw( QString( "Database Error executing query." ));
569  }
570 
571  while (query.next())
572  {
573  DTC::LogMessage *pLogMessage = pList->AddNewLogMessage();
574 
575  pLogMessage->setHostName( query.value(0).toString() );
576  pLogMessage->setApplication( query.value(1).toString() );
577  pLogMessage->setPID( query.value(2).toInt() );
578  pLogMessage->setTID( query.value(3).toInt() );
579  pLogMessage->setThread( query.value(4).toString() );
580  pLogMessage->setFilename( query.value(5).toString() );
581  pLogMessage->setLine( query.value(6).toInt() );
582  pLogMessage->setFunction( query.value(7).toString() );
583  pLogMessage->setTime(MythDate::as_utc(query.value(8).toDateTime()));
584  pLogMessage->setLevel( logLevelGetName(
585  (LogLevel_t)query.value(9).toInt()) );
586  pLogMessage->setMessage( query.value(10).toString() );
587  }
588  }
589 
590  return pList;
591 }
592 
594 //
596 
598 {
599  auto *pList = new DTC::FrontendList();
600  QMap<QString, Frontend*> frontends;
601  if (OnLine)
602  frontends = gBackendContext->GetConnectedFrontends();
603  else
604  frontends = gBackendContext->GetFrontends();
605 
606  for (auto * fe : qAsConst(frontends))
607  {
608  DTC::Frontend *pFrontend = pList->AddNewFrontend();
609  pFrontend->setName(fe->m_name);
610  pFrontend->setIP(fe->m_ip.toString());
611  int port = gCoreContext->GetNumSettingOnHost("FrontendStatusPort",
612  fe->m_name, 6547);
613  pFrontend->setPort(port);
614  pFrontend->setOnLine(fe->m_connectionCount > 0);
615  }
616 
617  return pList;
618 }
619 
621 //
623 
624 QString Myth::GetSetting( const QString &sHostName,
625  const QString &sKey,
626  const QString &sDefault )
627 {
628  if (sKey.isEmpty())
629  throw( QString("Missing or empty Key (settings.value)") );
630 
631  if (sHostName == "_GLOBAL_")
632  {
633  MSqlQuery query(MSqlQuery::InitCon());
634 
635  query.prepare("SELECT data FROM settings "
636  "WHERE value = :VALUE "
637  "AND (hostname IS NULL)" );
638 
639  query.bindValue(":VALUE", sKey );
640 
641  if (!query.exec())
642  {
643  MythDB::DBError("API Myth/GetSetting ", query);
644  throw( QString( "Database Error executing query." ));
645  }
646 
647  return query.next() ? query.value(0).toString() : sDefault;
648  }
649 
650  QString hostname = sHostName;
651 
652  if (sHostName.isEmpty())
654 
655  return gCoreContext->GetSettingOnHost(sKey, hostname, sDefault);
656 }
657 
659 //
661 
662 DTC::SettingList *Myth::GetSettingList(const QString &sHostName)
663 {
664 
665  MSqlQuery query(MSqlQuery::InitCon());
666 
667  if (!query.isConnected())
668  {
669  throw( QString("Database not open while trying to load settings for host: %1")
670  .arg( sHostName ));
671  }
672 
673  auto *pList = new DTC::SettingList();
674 
675  //pList->setObjectName( "Settings" );
676  pList->setHostName ( sHostName );
677 
678  // ------------------------------------------------------------------
679  // Looking to return all Setting for supplied hostname
680  // ------------------------------------------------------------------
681 
682  if (sHostName.isEmpty())
683  {
684  query.prepare("SELECT value, data FROM settings "
685  "WHERE (hostname IS NULL)" );
686  }
687  else
688  {
689  query.prepare("SELECT value, data FROM settings "
690  "WHERE (hostname = :HOSTNAME)" );
691 
692  query.bindValue(":HOSTNAME", sHostName );
693  }
694 
695  if (!query.exec())
696  {
697  // clean up unused object we created.
698 
699  delete pList;
700 
701  MythDB::DBError("MythAPI::GetSetting() w/o key ", query);
702  throw( QString( "Database Error executing query." ));
703  }
704 
705  while (query.next())
706  pList->Settings().insert( query.value(0).toString(), query.value(1) );
707 
708  return pList;
709 }
710 
712 //
714 
715 bool Myth::PutSetting( const QString &sHostName,
716  const QString &sKey,
717  const QString &sValue )
718 {
719  if (!sKey.isEmpty())
720  {
721  return gCoreContext->SaveSettingOnHost( sKey, sValue, sHostName );
722  }
723 
724  throw ( QString( "Key Required" ));
725 }
726 
728 //
730 
731 bool Myth::ChangePassword( const QString &sUserName,
732  const QString &sOldPassword,
733  const QString &sNewPassword )
734 {
735  LOG(VB_GENERAL, LOG_NOTICE, "ChangePassword is deprecated, use "
736  "ManageDigestUser.");
737 
738  return ( ManageDigestUser("ChangePassword", sUserName, sOldPassword,
739  sNewPassword, "") );
740 }
741 
743 //
745 
746 bool Myth::TestDBSettings( const QString &sHostName,
747  const QString &sUserName,
748  const QString &sPassword,
749  const QString &sDBName,
750  int dbPort)
751 {
752  bool bResult = false;
753 
754  QString db("mythconverg");
755  int port = 3306;
756 
757  if (!sDBName.isEmpty())
758  db = sDBName;
759 
760  if (dbPort != 0)
761  port = dbPort;
762 
763  bResult = TestDatabase(sHostName, sUserName, sPassword, db, port);
764 
765  return bResult;
766 }
767 
769 //
771 
772 bool Myth::SendMessage( const QString &sMessage,
773  const QString &sAddress,
774  int udpPort,
775  int Timeout)
776 {
777  bool bResult = false;
778 
779  if (sMessage.isEmpty())
780  return bResult;
781 
782  if (Timeout < 0 || Timeout > 999)
783  Timeout = 0;
784 
785  QString xmlMessage =
786  "<mythmessage version=\"1\">\n"
787  " <text>" + sMessage + "</text>\n"
788  " <timeout>" + QString::number(Timeout) + "</timeout>\n"
789  "</mythmessage>";
790 
791  QHostAddress address = QHostAddress::Broadcast;
792  unsigned short port = 6948;
793 
794  if (!sAddress.isEmpty())
795  address.setAddress(sAddress);
796 
797  if (udpPort != 0)
798  port = udpPort;
799 
800  auto *sock = new QUdpSocket();
801  QByteArray utf8 = xmlMessage.toUtf8();
802  int size = utf8.length();
803 
804  if (sock->writeDatagram(utf8.constData(), size, address, port) < 0)
805  {
806  LOG(VB_GENERAL, LOG_ERR,
807  QString("Failed to send UDP/XML packet (Message: %1 "
808  "Address: %2 Port: %3")
809  .arg(sMessage, sAddress, QString::number(port)));
810  }
811  else
812  {
813  LOG(VB_GENERAL, LOG_DEBUG,
814  QString("UDP/XML packet sent! (Message: %1 Address: %2 Port: %3")
815  .arg(sMessage,
816  address.toString().toLocal8Bit(),
817  QString::number(port)));
818  bResult = true;
819  }
820 
821  sock->deleteLater();
822 
823  return bResult;
824 }
825 
826 bool Myth::SendNotification( bool bError,
827  const QString &Type,
828  const QString &sMessage,
829  const QString &sOrigin,
830  const QString &sDescription,
831  const QString &sImage,
832  const QString &sExtra,
833  const QString &sProgressText,
834  float fProgress,
835  int Duration,
836  bool bFullscreen,
837  uint Visibility,
838  uint Priority,
839  const QString &sAddress,
840  int udpPort )
841 {
842  bool bResult = false;
843 
844  if (sMessage.isEmpty())
845  return bResult;
846 
847  if (Duration < 0 || Duration > 999)
848  Duration = -1;
849 
850  QString xmlMessage =
851  "<mythnotification version=\"1\">\n"
852  " <text>" + sMessage + "</text>\n"
853  " <origin>" + (sOrigin.isNull() ? tr("MythServices") : sOrigin) + "</origin>\n"
854  " <description>" + sDescription + "</description>\n"
855  " <timeout>" + QString::number(Duration) + "</timeout>\n"
856  " <image>" + sImage + "</image>\n"
857  " <extra>" + sExtra + "</extra>\n"
858  " <progress_text>" + sProgressText + "</progress_text>\n"
859  " <progress>" + QString::number(fProgress) + "</progress>\n"
860  " <fullscreen>" + (bFullscreen ? "true" : "false") + "</fullscreen>\n"
861  " <visibility>" + QString::number(Visibility) + "</visibility>\n"
862  " <priority>" + QString::number(Priority) + "</priority>\n"
863  " <type>" + (bError ? "error" : Type) + "</type>\n"
864  "</mythnotification>";
865 
866  QHostAddress address = QHostAddress::Broadcast;
867  unsigned short port = 6948;
868 
869  if (!sAddress.isEmpty())
870  address.setAddress(sAddress);
871 
872  if (udpPort != 0)
873  port = udpPort;
874 
875  auto *sock = new QUdpSocket();
876  QByteArray utf8 = xmlMessage.toUtf8();
877  int size = utf8.length();
878 
879  if (sock->writeDatagram(utf8.constData(), size, address, port) < 0)
880  {
881  LOG(VB_GENERAL, LOG_ERR,
882  QString("Failed to send UDP/XML packet (Notification: %1 "
883  "Address: %2 Port: %3")
884  .arg(sMessage, sAddress, QString::number(port)));
885  }
886  else
887  {
888  LOG(VB_GENERAL, LOG_DEBUG,
889  QString("UDP/XML packet sent! (Notification: %1 Address: %2 Port: %3")
890  .arg(sMessage,
891  address.toString().toLocal8Bit(), QString::number(port)));
892  bResult = true;
893  }
894 
895  sock->deleteLater();
896 
897  return bResult;
898 }
899 
901 //
903 
905 {
906  bool bResult = false;
907 
908  DBUtil dbutil;
910  QString filename;
911 
912  LOG(VB_GENERAL, LOG_NOTICE, "Performing API invoked DB Backup.");
913 
914  status = DBUtil::BackupDB(filename);
915 
916  if (status == kDB_Backup_Completed)
917  {
918  LOG(VB_GENERAL, LOG_NOTICE, "Database backup succeeded.");
919  bResult = true;
920  }
921  else
922  LOG(VB_GENERAL, LOG_ERR, "Database backup failed.");
923 
924  return bResult;
925 }
926 
928 //
930 
931 bool Myth::CheckDatabase( bool repair )
932 {
933  LOG(VB_GENERAL, LOG_NOTICE, "Performing API invoked DB Check.");
934 
935  bool bResult = DBUtil::CheckTables(repair);
936 
937  if (bResult)
938  LOG(VB_GENERAL, LOG_NOTICE, "Database check complete.");
939  else
940  LOG(VB_GENERAL, LOG_ERR, "Database check failed.");
941 
942  return bResult;
943 }
944 
946 {
947  auto *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler());
948  if (scheduler == nullptr)
949  return false;
950  scheduler->DelayShutdown();
951  LOG(VB_GENERAL, LOG_NOTICE, "Shutdown delayed 5 minutes for external application.");
952  return true;
953 }
954 
956 //
958 
960 {
962  LOG(VB_GENERAL, LOG_NOTICE, "Profile Submission...");
963  profile.GenerateUUIDs();
964  bool bResult = profile.SubmitProfile();
965  if (bResult)
966  LOG(VB_GENERAL, LOG_NOTICE, "Profile Submitted.");
967 
968  return bResult;
969 }
970 
972 //
974 
976 {
978  LOG(VB_GENERAL, LOG_NOTICE, "Profile Deletion...");
979  profile.GenerateUUIDs();
980  bool bResult = profile.DeleteProfile();
981  if (bResult)
982  LOG(VB_GENERAL, LOG_NOTICE, "Profile Deleted.");
983 
984  return bResult;
985 }
986 
988 //
990 
992 {
993  QString sProfileURL;
994 
996  profile.GenerateUUIDs();
997  sProfileURL = profile.GetProfileURL();
998  LOG(VB_GENERAL, LOG_NOTICE, QString("ProfileURL: %1").arg(sProfileURL));
999 
1000  return sProfileURL;
1001 }
1002 
1004 //
1006 
1008 {
1009  QString sProfileUpdate;
1010 
1012  profile.GenerateUUIDs();
1013  QDateTime tUpdated;
1014  tUpdated = profile.GetLastUpdate();
1015  sProfileUpdate = tUpdated.toString(
1016  gCoreContext->GetSetting( "DateFormat", "MM.dd.yyyy"));
1017 
1018  return sProfileUpdate;
1019 }
1020 
1022 //
1024 
1026 {
1027  QString sProfileText;
1028 
1030  sProfileText = HardwareProfile::GetHardwareProfile();
1031 
1032  return sProfileText;
1033 }
1034 
1036 //
1038 
1040 {
1041 
1042  // ----------------------------------------------------------------------
1043  // Create and populate a Configuration object
1044  // ----------------------------------------------------------------------
1045 
1046  auto *pInfo = new DTC::BackendInfo();
1047  DTC::BuildInfo *pBuild = pInfo->Build();
1048  DTC::EnvInfo *pEnv = pInfo->Env();
1049  DTC::LogInfo *pLog = pInfo->Log();
1050 
1051  pBuild->setVersion ( MYTH_SOURCE_VERSION );
1052  pBuild->setLibX264 ( CONFIG_LIBX264 );
1053  pBuild->setLibDNS_SD ( CONFIG_LIBDNS_SD );
1054  pEnv->setLANG ( qEnvironmentVariable("LANG") );
1055  pEnv->setLCALL ( qEnvironmentVariable("LC_ALL") );
1056  pEnv->setLCCTYPE ( qEnvironmentVariable("LC_CTYPE") );
1057  pEnv->setHOME ( qEnvironmentVariable("HOME") );
1058  pEnv->setMYTHCONFDIR ( qEnvironmentVariable("MYTHCONFDIR") );
1059  pLog->setLogArgs ( logPropagateArgs );
1060 
1061  // ----------------------------------------------------------------------
1062  // Return the pointer... caller is responsible to delete it!!!
1063  // ----------------------------------------------------------------------
1064 
1065  return pInfo;
1066 
1067 }
1068 
1070 //
1072 
1073 bool Myth::ManageDigestUser( const QString &sAction,
1074  const QString &sUserName,
1075  const QString &sPassword,
1076  const QString &sNewPassword,
1077  const QString &sAdminPassword )
1078 {
1079 
1080  DigestUserActions sessionAction = DIGEST_USER_ADD;
1081 
1082  if (sAction == "Add")
1083  sessionAction = DIGEST_USER_ADD;
1084  else if (sAction == "Remove")
1085  sessionAction = DIGEST_USER_REMOVE;
1086  else if (sAction == "ChangePassword")
1087  sessionAction = DIGEST_USER_CHANGE_PW;
1088  else
1089  {
1090  LOG(VB_GENERAL, LOG_ERR, QString("Action must be Add, Remove or "
1091  "ChangePassword, not '%1'")
1092  .arg(sAction));
1093  return false;
1094  }
1095 
1096  return MythSessionManager::ManageDigestUser(sessionAction, sUserName,
1097  sPassword, sNewPassword,
1098  sAdminPassword);
1099 }
1100 
1102 //
1104 
1105 bool Myth::ManageUrlProtection( const QString &sServices,
1106  const QString &sAdminPassword )
1107 {
1108  if (!MythSessionManager::IsValidUser("admin"))
1109  {
1110  LOG(VB_GENERAL, LOG_ERR, QString("Backend has no '%1' user!")
1111  .arg("admin"));
1112  return false;
1113  }
1114 
1115  if (MythSessionManager::CreateDigest("admin", sAdminPassword) !=
1117  {
1118  LOG(VB_GENERAL, LOG_ERR, QString("Incorrect password for user: %1")
1119  .arg("admin"));
1120  return false;
1121  }
1122 
1123  QStringList serviceList = sServices.split(",");
1124 
1125  serviceList.removeDuplicates();
1126 
1127  QStringList protectedURLs;
1128 
1129  if (serviceList.size() == 1 && serviceList.first() == "All")
1130  {
1131  for (const QString& service : KnownServices)
1132  protectedURLs << '/' + service;
1133  }
1134  else if (serviceList.size() == 1 && serviceList.first() == "None")
1135  {
1136  protectedURLs << "Unprotected";
1137  }
1138  else
1139  {
1140  for (const QString& service : serviceList)
1141  {
1142  if (KnownServices.contains(service))
1143  protectedURLs << '/' + service;
1144  else
1145  LOG(VB_GENERAL, LOG_ERR, QString("Invalid service name: '%1'")
1146  .arg(service));
1147  }
1148  }
1149 
1150  if (protectedURLs.isEmpty())
1151  {
1152  LOG(VB_GENERAL, LOG_ERR, "No valid Services were found");
1153  return false;
1154  }
1155 
1156  return gCoreContext->SaveSettingOnHost("HTTP/Protected/Urls",
1157  protectedURLs.join(';'), "");
1158 }
serviceUtil.h
Myth::GetBackendInfo
DTC::BackendInfo * GetBackendInfo(void) override
Definition: myth.cpp:1039
Scheduler
Definition: scheduler.h:45
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:811
MythSessionManager::IsValidUser
static bool IsValidUser(const QString &username)
Check if the given user exists but not whether there is a valid session open for them!
Definition: mythsession.cpp:151
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
hardwareprofile.h
MythSessionManager::GetPasswordDigest
static QString GetPasswordDigest(const QString &username)
Load the password digest for comparison in the HTTP Auth code.
Definition: mythsession.cpp:224
KnownServices
const QStringList KnownServices
Definition: serviceUtil.h:59
Myth::BackupDatabase
bool BackupDatabase(void) override
Definition: myth.cpp:904
DTC::BuildInfo
Definition: buildInfo.h:22
Myth::DelayShutdown
bool DelayShutdown(void) override
Definition: myth.cpp:945
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:84
MusicMetadata::Filename
QString Filename(bool find=true)
Definition: musicmetadata.cpp:959
DatabaseParams::m_dbHostName
QString m_dbHostName
database server
Definition: mythdbparams.h:22
DTC::SettingList
Definition: settingList.h:23
Myth::GetStorageGroupDirs
DTC::StorageGroupDirList * GetStorageGroupDirs(const QString &GroupName, const QString &HostName) override
Definition: myth.cpp:217
dbutil.h
backendcontext.h
DTC::FrontendList
Definition: frontendList.h:24
Myth::RemoveStorageGroupDir
bool RemoveStorageGroupDir(const QString &GroupName, const QString &DirName, const QString &HostName) override
Definition: myth.cpp:359
DIGEST_USER_CHANGE_PW
@ DIGEST_USER_CHANGE_PW
Definition: mythsession.h:13
Myth::GetSetting
QString GetSetting(const QString &HostName, const QString &Key, const QString &Default) override
Definition: myth.cpp:624
Myth::ProfileSubmit
bool ProfileSubmit(void) override
Definition: myth.cpp:959
MythCoreContext::GetScheduler
MythScheduler * GetScheduler(void)
Definition: mythcorecontext.cpp:1875
Myth::AddStorageGroupDir
bool AddStorageGroupDir(const QString &GroupName, const QString &DirName, const QString &HostName) override
Definition: myth.cpp:297
getDiskSpace
int64_t getDiskSpace(const QString &file_on_disk, int64_t &total, int64_t &used)
Definition: mythcoreutil.cpp:33
MythDate::as_utc
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
Definition: mythdate.cpp:27
DTC::TimeZoneInfo
Definition: timeZoneInfo.h:20
MythTZ::getTimeZoneID
QString getTimeZoneID(void)
Returns the zoneinfo time zone ID or as much time zone information as possible.
Definition: mythtimezone.cpp:32
DatabaseParams
Structure containing the basic Database parameters.
Definition: mythdbparams.h:10
DTC::ConnectionInfo
Definition: connectionInfo.h:24
Myth::GetHostName
QString GetHostName() override
Definition: myth.cpp:137
DTC::VersionInfo
Definition: versionInfo.h:22
Scheduler::DelayShutdown
void DelayShutdown()
Definition: scheduler.cpp:3077
mythcoreutil.h
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:205
mythdbcon.h
TestDatabase
bool TestDatabase(const QString &dbHostName, const QString &dbUserName, QString dbPassword, QString dbName, int dbPort)
Definition: mythdbcon.cpp:41
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:617
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythSessionManager::CreateDigest
static QByteArray CreateDigest(const QString &username, const QString &password)
Generate a digest string.
Definition: mythsession.cpp:536
Myth::SendMessage
bool SendMessage(const QString &Message, const QString &Address, int udpPort, int Timeout) override
Definition: myth.cpp:772
DBUtil::CheckTables
static bool CheckTables(bool repair=false, const QString &options="QUICK")
Checks database tables.
Definition: dbutil.cpp:279
DatabaseParams::m_dbType
QString m_dbType
database type (MySQL, Postgres, etc.)
Definition: mythdbparams.h:28
Myth::GetFormatDate
QString GetFormatDate(const QDateTime &Date, bool ShortDate) override
Definition: myth.cpp:415
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:50
gBackendContext
BackendContext * gBackendContext
Definition: backendcontext.cpp:9
myth.h
DTC::LogInfo
Definition: logInfo.h:22
MythDate::kDateTimeShort
@ kDateTimeShort
Default local time.
Definition: mythdate.h:24
scheduler.h
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
DatabaseParams::m_wolReconnect
std::chrono::seconds m_wolReconnect
seconds to wait for reconnect
Definition: mythdbparams.h:35
Myth::TestDBSettings
bool TestDBSettings(const QString &HostName, const QString &UserName, const QString &Password, const QString &DBName, int dbPort) override
Definition: myth.cpp:746
Myth::GetConnectionInfo
DTC::ConnectionInfo * GetConnectionInfo(const QString &Pin) override
Definition: myth.cpp:56
Myth::GetTimeZone
DTC::TimeZoneInfo * GetTimeZone() override
Definition: myth.cpp:400
DTC::LogMessageList
Definition: logMessageList.h:15
DatabaseParams::m_dbPort
int m_dbPort
database port
Definition: mythdbparams.h:24
mythdate.h
DTC::WOLInfo
Definition: wolInfo.h:22
mythlogging.h
logLevelGetName
QString logLevelGetName(LogLevel_t level)
Map a log level enumerated value back to the name.
Definition: logging.cpp:771
DTC::LogMessage
Definition: logMessage.h:20
MythSessionManager::ManageDigestUser
static bool ManageDigestUser(DigestUserActions action, const QString &username, const QString &password, const QString &newPassword, const QString &adminPassword)
Manage digest user entries.
Definition: mythsession.cpp:550
hardwareprofile.scan.profile
profile
Definition: scan.py:99
DTC::VersionInfo::Version
QString Version
Definition: versionInfo.h:29
DatabaseParams::m_dbHostPing
bool m_dbHostPing
Can we test connectivity using ping?
Definition: mythdbparams.h:23
DTC::StorageGroupDir
Definition: storageGroupDir.h:14
DTC::StorageGroupDirList
Definition: storageGroupDirList.h:14
HardwareProfile
Definition: hardwareprofile.h:16
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:549
MythCoreContext::GetBackendServerIP
QString GetBackendServerIP(void)
Returns the IP address of the locally defined backend IP.
Definition: mythcorecontext.cpp:1002
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:227
BackendContext::GetFrontends
QMap< QString, Frontend * > GetFrontends() const
Definition: backendcontext.h:43
Myth::GetFormatDateTime
QString GetFormatDateTime(const QDateTime &DateTime, bool ShortDate) override
Definition: myth.cpp:428
logLevelGet
LogLevel_t logLevelGet(const QString &level)
Map a log level name back to the enumerated value.
Definition: logging.cpp:749
Myth::ProfileUpdated
QString ProfileUpdated(void) override
Definition: myth.cpp:1007
kDB_Backup_Completed
@ kDB_Backup_Completed
Definition: dbutil.h:13
HardwareProfile::GetHardwareProfile
static QString GetHardwareProfile(void)
Definition: hardwareprofile.cpp:263
Myth::ProfileDelete
bool ProfileDelete(void) override
Definition: myth.cpp:975
MythDate::kAutoYear
@ kAutoYear
Add year only if different from current year.
Definition: mythdate.h:28
DigestUserActions
DigestUserActions
Definition: mythsession.h:10
MythDate::kDateShort
@ kDateShort
Default local time.
Definition: mythdate.h:20
DBUtil
Aggregates database and DBMS utility functions.
Definition: dbutil.h:30
MythCoreContext::GetNumSettingOnHost
int GetNumSettingOnHost(const QString &key, const QString &host, int defaultval=0)
Definition: mythcorecontext.cpp:941
DBUtil::BackupDB
static MythDBBackupStatus BackupDB(QString &filename, bool disableRotation=false)
Requests a backup of the database.
Definition: dbutil.cpp:190
Myth::PutSetting
bool PutSetting(const QString &HostName, const QString &Key, const QString &Value) override
Definition: myth.cpp:715
storagegroup.h
DatabaseParams::m_dbPassword
QString m_dbPassword
DB password.
Definition: mythdbparams.h:26
PID
Contains Packet Identifier numeric values.
Definition: mpegtables.h:206
Myth::SendNotification
bool SendNotification(bool Error, const QString &Type, const QString &Message, const QString &Origin, const QString &Description, const QString &Image, const QString &Extra, const QString &ProgressText, float Progress, int Duration, bool Fullscreen, uint Visibility, uint Priority, const QString &Address, int udpPort) override
Definition: myth.cpp:826
DatabaseParams::m_wolRetry
int m_wolRetry
times to retry to reconnect
Definition: mythdbparams.h:36
DatabaseParams::m_dbName
QString m_dbName
database name
Definition: mythdbparams.h:27
MSqlQuery::isConnected
bool isConnected(void) const
Only updated once during object creation.
Definition: mythdbcon.h:138
uint
unsigned int uint
Definition: compat.h:81
MythDBBackupStatus
MythDBBackupStatus
Definition: dbutil.h:9
DIGEST_USER_REMOVE
@ DIGEST_USER_REMOVE
Definition: mythsession.h:12
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:54
DTC::EnvInfo
Definition: envInfo.h:22
Myth::GetKeys
QStringList GetKeys() override
Definition: myth.cpp:183
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:34
MythDate::kSimplify
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
Definition: mythdate.h:26
BackendContext::GetConnectedFrontends
QMap< QString, Frontend * > GetConnectedFrontends() const
Definition: backendcontext.h:42
MythTZ::calc_utc_offset
int calc_utc_offset(void)
Definition: mythtimezone.cpp:20
Myth::CheckDatabase
bool CheckDatabase(bool Repair) override
Definition: myth.cpp:931
Myth::ManageDigestUser
bool ManageDigestUser(const QString &Action, const QString &UserName, const QString &Password, const QString &NewPassword, const QString &AdminPassword) override
Definition: myth.cpp:1073
Myth::GetLogs
DTC::LogMessageList * GetLogs(const QString &HostName, const QString &Application, int PID, int TID, const QString &Thread, const QString &Filename, int Line, const QString &Function, const QDateTime &FromTime, const QDateTime &ToTime, const QString &Level, const QString &MsgContains) override
Definition: myth.cpp:464
mythcorecontext.h
DTC::BackendInfo
Definition: backendInfo.h:24
DatabaseParams::m_wolCommand
QString m_wolCommand
command to use for wake-on-lan
Definition: mythdbparams.h:37
MythCoreContext::GetSettingOnHost
QString GetSettingOnHost(const QString &key, const QString &host, const QString &defaultval="")
Definition: mythcorecontext.cpp:924
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:887
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:17
DatabaseParams::m_dbUserName
QString m_dbUserName
DB user name.
Definition: mythdbparams.h:25
DTC::DatabaseInfo
Definition: databaseInfo.h:22
Myth::ParseISODateString
QDateTime ParseISODateString(const QString &DateTime) override
Definition: myth.cpp:450
MythDate::kDateFull
@ kDateFull
Default local time.
Definition: mythdate.h:19
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:836
DIGEST_USER_ADD
@ DIGEST_USER_ADD
Definition: mythsession.h:11
Myth::GetSettingList
DTC::SettingList * GetSettingList(const QString &HostName) override
Definition: myth.cpp:662
logPropagateArgs
QString logPropagateArgs
Definition: logging.cpp:82
Myth::ChangePassword
bool ChangePassword(const QString &UserName, const QString &OldPassword, const QString &NewPassword) override
Definition: myth.cpp:731
Myth::GetHosts
QStringList GetHosts() override
Definition: myth.cpp:148
kDB_Backup_Unknown
@ kDB_Backup_Unknown
Definition: dbutil.h:11
musicbrainzngs.caa.hostname
string hostname
Definition: caa.py:17
DatabaseParams::m_localEnabled
bool m_localEnabled
true if localHostName is not default
Definition: mythdbparams.h:30
MythDate::kDateTimeFull
@ kDateTimeFull
Default local time.
Definition: mythdate.h:23
Myth::ManageUrlProtection
bool ManageUrlProtection(const QString &Services, const QString &AdminPassword) override
Definition: myth.cpp:1105
MythDate::kTime
@ kTime
Default local time.
Definition: mythdate.h:22
Myth::ProfileText
QString ProfileText(void) override
Definition: myth.cpp:1025
DatabaseParams::m_wolEnabled
bool m_wolEnabled
true if wake-on-lan params are used
Definition: mythdbparams.h:34
build_compdb.filename
filename
Definition: build_compdb.py:21
DatabaseParams::m_localHostName
QString m_localHostName
name used for loading/saving settings
Definition: mythdbparams.h:31
MythCoreContext::SaveSettingOnHost
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
Definition: mythcorecontext.cpp:889
DTC::Frontend
Definition: libs/libmythservicecontracts/datacontracts/frontend.h:24
Priority
Definition: channelsettings.cpp:216
mythtimezone.h
Myth::ProfileURL
QString ProfileURL(void) override
Definition: myth.cpp:991
Myth::GetFormatTime
QString GetFormatTime(const QDateTime &Time) override
Definition: myth.cpp:441
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:896
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:836
DTC::LabelValue
Definition: labelValue.h:19
Myth::GetFrontends
DTC::FrontendList * GetFrontends(bool OnLine) override
Definition: myth.cpp:597