MythTV  0.27pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
myth.cpp
Go to the documentation of this file.
1 
2 // 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., 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 "myth.h"
27 
28 #include <QDir>
29 #include <QCryptographicHash>
30 #include <QHostAddress>
31 #include <QUdpSocket>
32 
33 #include "version.h"
34 #include "mythversion.h"
35 #include "mythcorecontext.h"
36 #include "mythdbcon.h"
37 #include "mythlogging.h"
38 #include "storagegroup.h"
39 #include "dbutil.h"
40 #include "hardwareprofile.h"
41 #include "mythtimezone.h"
42 #include "mythdate.h"
43 
45 //
47 
49 {
50  QString sSecurityPin = gCoreContext->GetSetting( "SecurityPin", "");
51 
52  if ( sSecurityPin.isEmpty() )
53  throw( QString( "No Security Pin assigned. Run mythtv-setup to set one." ));
54  //SB: UPnPResult_HumanInterventionRequired,
55 
56  if ((sSecurityPin != "0000" ) && ( sPin != sSecurityPin ))
57  throw( QString( "Not Authorized" ));
58  //SB: UPnPResult_ActionNotAuthorized );
59 
61 
62  // ----------------------------------------------------------------------
63  // Check for DBHostName of "localhost" and change to public name or IP
64  // ----------------------------------------------------------------------
65 
66  QString sServerIP = gCoreContext->GetSetting( "BackendServerIP", "localhost" );
67  //QString sPeerIP = pRequest->GetPeerAddress();
68 
69  if ((params.dbHostName == "localhost") &&
70  (sServerIP != "localhost")) // &&
71  //(sServerIP != sPeerIP ))
72  {
73  params.dbHostName = sServerIP;
74  }
75 
76  // ----------------------------------------------------------------------
77  // Create and populate a ConnectionInfo object
78  // ----------------------------------------------------------------------
79 
81  DTC::DatabaseInfo *pDatabase = pInfo->Database();
82  DTC::WOLInfo *pWOL = pInfo->WOL();
83  DTC::VersionInfo *pVersion = pInfo->Version();
84 
85  pDatabase->setHost ( params.dbHostName );
86  pDatabase->setPing ( params.dbHostPing );
87  pDatabase->setPort ( params.dbPort );
88  pDatabase->setUserName ( params.dbUserName );
89  pDatabase->setPassword ( params.dbPassword );
90  pDatabase->setName ( params.dbName );
91  pDatabase->setType ( params.dbType );
92  pDatabase->setLocalEnabled ( params.localEnabled );
93  pDatabase->setLocalHostName( params.localHostName );
94 
95  pWOL->setEnabled ( params.wolEnabled );
96  pWOL->setReconnect ( params.wolReconnect );
97  pWOL->setRetry ( params.wolRetry );
98  pWOL->setCommand ( params.wolCommand );
99 
100  pVersion->setVersion ( MYTH_SOURCE_VERSION );
101  pVersion->setBranch ( MYTH_SOURCE_PATH );
102  pVersion->setProtocol ( MYTH_PROTO_VERSION );
103  pVersion->setBinary ( MYTH_BINARY_VERSION );
104  pVersion->setSchema ( MYTH_DATABASE_VERSION );
105 
106  // ----------------------------------------------------------------------
107  // Return the pointer... caller is responsible to delete it!!!
108  // ----------------------------------------------------------------------
109 
110  return pInfo;
111 }
112 
114 //
116 
118 {
119  if (!gCoreContext)
120  throw( QString( "No MythCoreContext in GetHostName." ));
121 
122  return gCoreContext->GetHostName();
123 }
125 //
127 
128 QStringList Myth::GetHosts( )
129 {
130  MSqlQuery query(MSqlQuery::InitCon());
131 
132  if (!query.isConnected())
133  throw( QString( "Database not open while trying to load list of hosts" ));
134 
135  query.prepare(
136  "SELECT DISTINCTROW hostname "
137  "FROM settings "
138  "WHERE (not isNull( hostname ))");
139 
140  if (!query.exec())
141  {
142  MythDB::DBError("MythAPI::GetHosts()", query);
143 
144  throw( QString( "Database Error executing query." ));
145  }
146 
147  // ----------------------------------------------------------------------
148  // return the results of the query
149  // ----------------------------------------------------------------------
150 
151  QStringList oList;
152 
153  while (query.next())
154  oList.append( query.value(0).toString() );
155 
156  return oList;
157 }
158 
160 //
162 
163 QStringList Myth::GetKeys()
164 {
165  MSqlQuery query(MSqlQuery::InitCon());
166 
167  if (!query.isConnected())
168  throw( QString("Database not open while trying to load settings"));
169 
170  query.prepare("SELECT DISTINCTROW value FROM settings;" );
171 
172  if (!query.exec())
173  {
174  MythDB::DBError("MythAPI::GetKeys()", query);
175 
176  throw( QString( "Database Error executing query." ));
177  }
178 
179  // ----------------------------------------------------------------------
180  // return the results of the query
181  // ----------------------------------------------------------------------
182 
183  QStringList oResults;
184 
185  //pResults->setObjectName( "KeyList" );
186 
187  while (query.next())
188  oResults.append( query.value(0).toString() );
189 
190  return oResults;
191 }
192 
194 //
196 
198  const QString &sHostName )
199 {
200  MSqlQuery query(MSqlQuery::InitCon());
201 
202  if (!query.isConnected())
203  throw( QString("Database not open while trying to list "
204  "Storage Group Dirs"));
205 
206  if (!sGroupName.isEmpty() && !sHostName.isEmpty())
207  {
208  query.prepare("SELECT id, groupname, hostname, dirname "
209  "FROM storagegroup "
210  "WHERE groupname = :GROUP AND hostname = :HOST "
211  "ORDER BY groupname, hostname, dirname" );
212  query.bindValue(":HOST", sHostName);
213  query.bindValue(":GROUP", sGroupName);
214  }
215  else if (!sHostName.isEmpty())
216  {
217  query.prepare("SELECT id, groupname, hostname, dirname "
218  "FROM storagegroup "
219  "WHERE hostname = :HOST "
220  "ORDER BY groupname, hostname, dirname" );
221  query.bindValue(":HOST", sHostName);
222  }
223  else if (!sGroupName.isEmpty())
224  {
225  query.prepare("SELECT id, groupname, hostname, dirname "
226  "FROM storagegroup "
227  "WHERE groupname = :GROUP "
228  "ORDER BY groupname, hostname, dirname" );
229  query.bindValue(":GROUP", sGroupName);
230  }
231  else
232  query.prepare("SELECT id, groupname, hostname, dirname "
233  "FROM storagegroup "
234  "ORDER BY groupname, hostname, dirname" );
235 
236  if (!query.exec())
237  {
238  MythDB::DBError("MythAPI::GetStorageGroupDirs()", query);
239 
240  throw( QString( "Database Error executing query." ));
241  }
242 
243  // ----------------------------------------------------------------------
244  // return the results of the query
245  // ----------------------------------------------------------------------
246 
248 
249  while (query.next())
250  {
251  DTC::StorageGroupDir *pStorageGroupDir = pList->AddNewStorageGroupDir();
252 
253  pStorageGroupDir->setId ( query.value(0).toInt() );
254  pStorageGroupDir->setGroupName ( query.value(1).toString() );
255  pStorageGroupDir->setHostName ( query.value(2).toString() );
256  pStorageGroupDir->setDirName ( query.value(3).toString() );
257  }
258 
259  return pList;
260 }
261 
263 //
265 
266 bool Myth::AddStorageGroupDir( const QString &sGroupName,
267  const QString &sDirName,
268  const QString &sHostName )
269 {
270  MSqlQuery query(MSqlQuery::InitCon());
271 
272  if (!query.isConnected())
273  throw( QString("Database not open while trying to add Storage Group "
274  "dir"));
275 
276  if (sGroupName.isEmpty())
277  throw ( QString( "Storage Group Required" ));
278 
279  if (sDirName.isEmpty())
280  throw ( QString( "Directory Name Required" ));
281 
282  if (sHostName.isEmpty())
283  throw ( QString( "HostName Required" ));
284 
285  query.prepare("SELECT COUNT(*) "
286  "FROM storagegroup "
287  "WHERE groupname = :GROUPNAME "
288  "AND dirname = :DIRNAME "
289  "AND hostname = :HOSTNAME;");
290  query.bindValue(":GROUPNAME", sGroupName );
291  query.bindValue(":DIRNAME" , sDirName );
292  query.bindValue(":HOSTNAME" , sHostName );
293  if (!query.exec())
294  {
295  MythDB::DBError("MythAPI::AddStorageGroupDir()", query);
296 
297  throw( QString( "Database Error executing query." ));
298  }
299 
300  if (query.next())
301  {
302  if (query.value(0).toInt() > 0)
303  return false;
304  }
305 
306  query.prepare("INSERT storagegroup "
307  "( groupname, dirname, hostname ) "
308  "VALUES "
309  "( :GROUPNAME, :DIRNAME, :HOSTNAME );");
310  query.bindValue(":GROUPNAME", sGroupName );
311  query.bindValue(":DIRNAME" , sDirName );
312  query.bindValue(":HOSTNAME" , sHostName );
313 
314  if (!query.exec())
315  {
316  MythDB::DBError("MythAPI::AddStorageGroupDir()", query);
317 
318  throw( QString( "Database Error executing query." ));
319  }
320 
321  return true;
322 }
323 
325 //
327 
328 bool Myth::RemoveStorageGroupDir( const QString &sGroupName,
329  const QString &sDirName,
330  const QString &sHostName )
331 {
332  MSqlQuery query(MSqlQuery::InitCon());
333 
334  if (!query.isConnected())
335  throw( QString("Database not open while trying to remove Storage "
336  "Group dir"));
337 
338  if (sGroupName.isEmpty())
339  throw ( QString( "Storage Group Required" ));
340 
341  if (sDirName.isEmpty())
342  throw ( QString( "Directory Name Required" ));
343 
344  if (sHostName.isEmpty())
345  throw ( QString( "HostName Required" ));
346 
347  query.prepare("DELETE "
348  "FROM storagegroup "
349  "WHERE groupname = :GROUPNAME "
350  "AND dirname = :DIRNAME "
351  "AND hostname = :HOSTNAME;");
352  query.bindValue(":GROUPNAME", sGroupName );
353  query.bindValue(":DIRNAME" , sDirName );
354  query.bindValue(":HOSTNAME" , sHostName );
355  if (!query.exec())
356  {
357  MythDB::DBError("MythAPI::AddStorageGroupDir()", query);
358 
359  throw( QString( "Database Error executing query." ));
360  }
361 
362  return true;
363 }
364 
366 //
368 
370 {
371  DTC::TimeZoneInfo *pResults = new DTC::TimeZoneInfo();
372 
373  pResults->setTimeZoneID( MythTZ::getTimeZoneID() );
374  pResults->setUTCOffset( MythTZ::calc_utc_offset() );
375  pResults->setCurrentDateTime( MythDate::current(true) );
376 
377  return pResults;
378 }
379 
381 //
383 
384 DTC::LogMessageList *Myth::GetLogs( const QString &HostName,
385  const QString &Application,
386  int PID,
387  int TID,
388  const QString &Thread,
389  const QString &Filename,
390  int Line,
391  const QString &Function,
392  const QDateTime &FromTime,
393  const QDateTime &ToTime,
394  const QString &Level,
395  const QString &MsgContains )
396 {
398 
399  MSqlQuery query(MSqlQuery::InitCon());
400 
401  // Get host name list
402  QString sql = "SELECT DISTINCT host FROM logging ORDER BY host ASC";
403  if (!query.exec(sql))
404  {
405  MythDB::DBError("Retrieving log host names", query);
406  throw( QString( "Database Error executing query." ));
407  }
408  while (query.next())
409  {
410  DTC::LabelValue *pLabelValue = pList->AddNewHostName();
411  QString availableHostName = query.value(0).toString();
412  pLabelValue->setValue ( availableHostName );
413  pLabelValue->setActive ( availableHostName == HostName );
414  pLabelValue->setSelected( availableHostName == HostName );
415  }
416  // Get application list
417  sql = "SELECT DISTINCT application FROM logging ORDER BY application ASC";
418  if (!query.exec(sql))
419  {
420  MythDB::DBError("Retrieving log applications", query);
421  throw( QString( "Database Error executing query." ));
422  }
423  while (query.next())
424  {
425  DTC::LabelValue *pLabelValue = pList->AddNewApplication();
426  QString availableApplication = query.value(0).toString();
427  pLabelValue->setValue ( availableApplication );
428  pLabelValue->setActive ( availableApplication == Application );
429  pLabelValue->setSelected( availableApplication == Application );
430  }
431 
432  if (!HostName.isEmpty() && !Application.isEmpty())
433  {
434  // Get log messages
435  sql = "SELECT host, application, pid, tid, thread, filename, "
436  " line, function, msgtime, level, message "
437  " FROM logging "
438  " WHERE host = COALESCE(:HOSTNAME, host) "
439  " AND application = COALESCE(:APPLICATION, application) "
440  " AND pid = COALESCE(:PID, pid) "
441  " AND tid = COALESCE(:TID, tid) "
442  " AND thread = COALESCE(:THREAD, thread) "
443  " AND filename = COALESCE(:FILENAME, filename) "
444  " AND line = COALESCE(:LINE, line) "
445  " AND function = COALESCE(:FUNCTION, function) "
446  " AND msgtime >= COALESCE(:FROMTIME, msgtime) "
447  " AND msgtime <= COALESCE(:TOTIME, msgtime) "
448  " AND level <= COALESCE(:LEVEL, level) "
449  ;
450  if (!MsgContains.isEmpty())
451  {
452  sql.append(" AND message LIKE :MSGCONTAINS ");
453  }
454  sql.append(" ORDER BY msgtime ASC;");
455 
456  query.prepare(sql);
457 
458  query.bindValue(":HOSTNAME", (HostName.isEmpty()) ? QString() : HostName);
459  query.bindValue(":APPLICATION", (Application.isEmpty()) ? QString() :
460  Application);
461  query.bindValue(":PID", ( PID == 0 ) ? QVariant(QVariant::ULongLong) :
462  (qint64)PID);
463  query.bindValue(":TID", ( TID == 0 ) ? QVariant(QVariant::ULongLong) :
464  (qint64)TID);
465  query.bindValue(":THREAD", (Thread.isEmpty()) ? QString() : Thread);
466  query.bindValue(":FILENAME", (Filename.isEmpty()) ? QString() : Filename);
467  query.bindValue(":LINE", ( Line == 0 ) ? QVariant(QVariant::ULongLong) :
468  (qint64)Line);
469  query.bindValue(":FUNCTION", (Function.isEmpty()) ? QString() : Function);
470  query.bindValue(":FROMTIME", (FromTime.isValid()) ? FromTime : QDateTime());
471  query.bindValue(":TOTIME", (ToTime.isValid()) ? ToTime : QDateTime());
472  query.bindValue(":LEVEL", (Level.isEmpty()) ?
473  QVariant(QVariant::ULongLong) :
474  (qint64)logLevelGet(Level));
475 
476  if (!MsgContains.isEmpty())
477  {
478  query.bindValue(":MSGCONTAINS", "%" + MsgContains + "%" );
479  }
480 
481  if (!query.exec())
482  {
483  MythDB::DBError("Retrieving log messages", query);
484  throw( QString( "Database Error executing query." ));
485  }
486 
487  while (query.next())
488  {
489  DTC::LogMessage *pLogMessage = pList->AddNewLogMessage();
490 
491  pLogMessage->setHostName( query.value(0).toString() );
492  pLogMessage->setApplication( query.value(1).toString() );
493  pLogMessage->setPID( query.value(2).toInt() );
494  pLogMessage->setTID( query.value(3).toInt() );
495  pLogMessage->setThread( query.value(4).toString() );
496  pLogMessage->setFilename( query.value(5).toString() );
497  pLogMessage->setLine( query.value(6).toInt() );
498  pLogMessage->setFunction( query.value(7).toString() );
499  pLogMessage->setTime(MythDate::as_utc(query.value(8).toDateTime()));
500  pLogMessage->setLevel( logLevelGetName(
501  (LogLevel_t)query.value(9).toInt()) );
502  pLogMessage->setMessage( query.value(10).toString() );
503  }
504  }
505 
506  return pList;
507 }
508 
510 //
512 
513 DTC::SettingList *Myth::GetSetting( const QString &sHostName,
514  const QString &sKey,
515  const QString &sDefault )
516 {
517 
518  MSqlQuery query(MSqlQuery::InitCon());
519 
520  if (!query.isConnected())
521  {
522  throw( QString("Database not open while trying to load setting: %1")
523  .arg( sKey ));
524  }
525 
526  // ----------------------------------------------------------------------
527 
528  DTC::SettingList *pList = new DTC::SettingList();
529 
530  //pList->setObjectName( "Settings" );
531  pList->setHostName ( sHostName );
532 
533  // ----------------------------------------------------------------------
534  // Format Results
535  // ----------------------------------------------------------------------
536 
537  if (!sKey.isEmpty())
538  {
539  // ------------------------------------------------------------------
540  // Key Supplied, lookup just its value.
541  // ------------------------------------------------------------------
542 
543  query.prepare("SELECT data, hostname from settings "
544  "WHERE value = :KEY AND "
545  "(hostname = :HOSTNAME OR hostname IS NULL) "
546  "ORDER BY hostname DESC;" );
547 
548  query.bindValue(":KEY" , sKey );
549  query.bindValue(":HOSTNAME", sHostName );
550 
551  if (!query.exec())
552  {
553  // clean up unused object we created.
554 
555  delete pList;
556 
557  MythDB::DBError("MythAPI::GetSetting() w/key ", query);
558 
559  throw( QString( "Database Error executing query." ));
560  }
561 
562  if (query.next())
563  {
564  if ( (sHostName.isEmpty()) ||
565  ((!sHostName.isEmpty()) &&
566  (sHostName == query.value(1).toString())))
567  {
568  pList->setHostName( query.value(1).toString() );
569 
570  pList->Settings().insert( sKey, query.value(0) );
571  }
572  }
573  }
574  else
575  {
576  // ------------------------------------------------------------------
577  // Looking to return all Setting for supplied hostname
578  // ------------------------------------------------------------------
579 
580  if (sHostName.isEmpty())
581  {
582  query.prepare("SELECT value, data FROM settings "
583  "WHERE (hostname IS NULL)" );
584  }
585  else
586  {
587  query.prepare("SELECT value, data FROM settings "
588  "WHERE (hostname = :HOSTNAME)" );
589 
590  query.bindValue(":HOSTNAME", sHostName );
591  }
592 
593  if (!query.exec())
594  {
595  // clean up unused object we created.
596 
597  delete pList;
598 
599  MythDB::DBError("MythAPI::GetSetting() w/o key ", query);
600  throw( QString( "Database Error executing query." ));
601  }
602 
603  while (query.next())
604  pList->Settings().insert( query.value(0).toString(), query.value(1) );
605  }
606 
607  // ----------------------------------------------------------------------
608  // Not found, so return the supplied default value
609  // ----------------------------------------------------------------------
610 
611  if (pList->Settings().count() == 0)
612  pList->Settings().insert( sKey, sDefault );
613 
614  return pList;
615 }
616 
618 //
620 
621 bool Myth::PutSetting( const QString &sHostName,
622  const QString &sKey,
623  const QString &sValue )
624 {
625  bool bResult = false;
626 
627  if (!sKey.isEmpty())
628  {
629  if ( gCoreContext->SaveSettingOnHost( sKey, sValue, sHostName ) )
630  bResult = true;
631 
632  return bResult;
633  }
634 
635  throw ( QString( "Key Required" ));
636 }
637 
639 //
641 
642 bool Myth::ChangePassword( const QString &sUserName,
643  const QString &sOldPassword,
644  const QString &sNewPassword )
645 {
646  bool bResult = false;
647 
648  if (sUserName.isEmpty())
649  {
650  throw ( QString( "UserName not supplied when trying to change "
651  "password." ) );
652  }
653 
654  if (sOldPassword.isEmpty())
655  {
656  throw ( QString( "Old Password not supplied when trying to change "
657  "password for '%1'." ).arg(sUserName) );
658  }
659 
660  if (sNewPassword.isEmpty())
661  {
662  throw ( QString( "New Password not supplied when trying to change "
663  "password for '%1'." ).arg(sUserName) );
664  }
665 
666  QCryptographicHash crypto( QCryptographicHash::Sha1 );
667 
668  crypto.addData( sOldPassword.toUtf8() );
669 
670  QString sPasswordHash( crypto.result().toBase64() );
671 
672  if ( sPasswordHash != gCoreContext->GetSetting( "HTTP/Protected/Password", ""))
673  {
674  throw ( QString( "Incorrect Old Password supplied when trying to "
675  "change password for '%1'." ).arg(sUserName) );
676  }
677 
678  crypto.reset();
679  crypto.addData( sNewPassword.toUtf8() );
680 
681  if (gCoreContext->SaveSettingOnHost( "HTTP/Protected/Password", crypto.result().toBase64(),
682  QString() ) )
683  {
685  bResult = true;
686  }
687 
688  return bResult;
689 }
690 
692 //
694 
695 bool Myth::TestDBSettings( const QString &sHostName,
696  const QString &sUserName,
697  const QString &sPassword,
698  const QString &sDBName,
699  int dbPort)
700 {
701  bool bResult = false;
702 
703  QString db("mythconverg");
704  int port = 3306;
705 
706  if (!sDBName.isEmpty())
707  db = sDBName;
708 
709  if (dbPort != 0)
710  port = dbPort;
711 
712  bResult = TestDatabase(sHostName, sUserName, sPassword, db, port);
713 
714  return bResult;
715 }
716 
718 //
720 
721 bool Myth::SendMessage( const QString &sMessage,
722  const QString &sAddress,
723  int udpPort,
724  int Timeout)
725 {
726  bool bResult = false;
727 
728  if (sMessage.isEmpty())
729  return bResult;
730 
731  if (Timeout < 0 || Timeout > 999)
732  Timeout = 0;
733 
734  QString xmlMessage =
735  "<mythmessage version=\"1\">\n"
736  " <text>" + sMessage + "</text>\n"
737  " <timeout>" + QString::number(Timeout) + "</timeout>\n"
738  "</mythmessage>";
739 
740  QHostAddress address = QHostAddress::Broadcast;
741  unsigned short port = 6948;
742 
743  if (!sAddress.isEmpty())
744  address.setAddress(sAddress);
745 
746  if (udpPort != 0)
747  port = udpPort;
748 
749  QUdpSocket *sock = new QUdpSocket();
750  QByteArray utf8 = xmlMessage.toUtf8();
751  int size = utf8.length();
752 
753  if (sock->writeDatagram(utf8.constData(), size, address, port) < 0)
754  {
755  LOG(VB_GENERAL, LOG_ERR,
756  QString("Failed to send UDP/XML packet (Message: %1 "
757  "Address: %2 Port: %3")
758  .arg(sMessage).arg(sAddress).arg(port));
759  }
760  else
761  {
762  LOG(VB_GENERAL, LOG_DEBUG,
763  QString("UDP/XML packet sent! (Message: %1 Address: %2 Port: %3")
764  .arg(sMessage)
765  .arg(address.toString().toLocal8Bit().constData()).arg(port));
766  bResult = true;
767  }
768 
769  sock->deleteLater();
770 
771  return bResult;
772 }
773 
775 //
777 
779 {
780  bool bResult = false;
781 
782  DBUtil *dbutil = new DBUtil();
784  QString filename;
785 
786  LOG(VB_GENERAL, LOG_NOTICE, "Performing API invoked DB Backup.");
787 
788  if (dbutil)
789  status = dbutil->BackupDB(filename);
790 
791  if (status == kDB_Backup_Completed)
792  {
793  LOG(VB_GENERAL, LOG_NOTICE, "Database backup succeeded.");
794  bResult = true;
795  }
796  else
797  LOG(VB_GENERAL, LOG_ERR, "Database backup failed.");
798 
799  delete dbutil;
800 
801  return bResult;
802 }
803 
805 //
807 
808 bool Myth::CheckDatabase( bool repair )
809 {
810  bool bResult = false;
811 
812  DBUtil *dbutil = new DBUtil();
813 
814  LOG(VB_GENERAL, LOG_NOTICE, "Performing API invoked DB Check.");
815 
816  if (dbutil)
817  bResult = dbutil->CheckTables(repair);
818 
819  if (bResult)
820  LOG(VB_GENERAL, LOG_NOTICE, "Database check complete.");
821  else
822  LOG(VB_GENERAL, LOG_ERR, "Database check failed.");
823 
824  delete dbutil;
825 
826  return bResult;
827 }
828 
830 //
832 
834 {
835  bool bResult = false;
836 
838  if (profile)
839  {
840  LOG(VB_GENERAL, LOG_NOTICE, "Profile Submission...");
841  profile->GenerateUUIDs();
842  bResult = profile->SubmitProfile();
843  if (bResult)
844  LOG(VB_GENERAL, LOG_NOTICE, "Profile Submitted.");
845  }
846  delete profile;
847 
848  return bResult;
849 }
850 
852 //
854 
856 {
857  bool bResult = false;
858 
860  if (profile)
861  {
862  LOG(VB_GENERAL, LOG_NOTICE, "Profile Deletion...");
863  profile->GenerateUUIDs();
864  bResult = profile->DeleteProfile();
865  if (bResult)
866  LOG(VB_GENERAL, LOG_NOTICE, "Profile Deleted.");
867  }
868  delete profile;
869 
870  return bResult;
871 }
872 
874 //
876 
878 {
879  QString sProfileURL;
880 
882  if (profile)
883  {
884  profile->GenerateUUIDs();
885  sProfileURL = profile->GetProfileURL();
886  LOG(VB_GENERAL, LOG_NOTICE, QString("ProfileURL: %1").arg(sProfileURL));
887  }
888  delete profile;
889 
890  return sProfileURL;
891 }
892 
894 //
896 
898 {
899  QString sProfileUpdate;
900 
902  if (profile)
903  {
904  profile->GenerateUUIDs();
905  QDateTime tUpdated;
906  tUpdated = profile->GetLastUpdate();
907  sProfileUpdate = tUpdated.toString(
908  gCoreContext->GetSetting( "DateFormat", "MM.dd.yyyy"));
909  }
910  delete profile;
911 
912  return sProfileUpdate;
913 }
914 
916 //
918 
920 {
921  QString sProfileText;
922 
924  if (profile)
925  sProfileText = profile->GetHardwareProfile();
926  delete profile;
927 
928  return sProfileText;
929 }
930