4#include <QCryptographicHash>
7#include <QNetworkRequest>
10#include "libmythbase/mythconfig.h"
21#include "libmythbase/mythversion.h"
34#if CONFIG_SYSTEMD_NOTIFY
35#include <systemd/sd-daemon.h>
36static inline void api_sd_notify(
const char *str) { sd_notify(0, str); };
47 qRegisterMetaType<V2ConnectionInfo*>(
"V2ConnectionInfo");
48 qRegisterMetaType<V2VersionInfo*>(
"V2VersionInfo");
49 qRegisterMetaType<V2DatabaseInfo*>(
"V2DatabaseInfo");
50 qRegisterMetaType<V2WOLInfo*>(
"V2WOLInfo");
51 qRegisterMetaType<V2StorageGroupDirList*>(
"V2StorageGroupDirList");
52 qRegisterMetaType<V2StorageGroupDir*>(
"V2StorageGroupDir");
53 qRegisterMetaType<V2TimeZoneInfo*>(
"V2TimeZoneInfo");
54 qRegisterMetaType<V2LogMessage*>(
"V2LogMessage");
55 qRegisterMetaType<V2LogMessageList*>(
"V2LogMessageList");
56 qRegisterMetaType<V2LabelValue*>(
"V2LabelValue");
57 qRegisterMetaType<V2Frontend*>(
"V2Frontend");
58 qRegisterMetaType<V2FrontendList*>(
"V2FrontendList");
59 qRegisterMetaType<V2SettingList*>(
"V2SettingList");
60 qRegisterMetaType<V2BackendInfo*>(
"V2BackendInfo");
61 qRegisterMetaType<V2EnvInfo*>(
"V2EnvInfo");
62 qRegisterMetaType<V2LogInfo*>(
"V2LogInfo");
63 qRegisterMetaType<V2BuildInfo*>(
"V2BuildInfo");
80 if ( sSecurityPin.isEmpty() )
81 throw( QString(
"No Security Pin assigned. Run mythtv-setup to set one." ));
84 if ((sSecurityPin !=
"0000" ) && ( sPin != sSecurityPin ))
85 throw( QString(
"Not Authorized" ));
97 if ((params.
m_dbHostName.compare(
"localhost",Qt::CaseInsensitive)==0
100 && !sServerIP.isEmpty())
111 if (addr.setAddress(dbHostName))
113 addr.setScopeId(QString());
114 dbHostName = addr.toString();
125 pDatabase->setHost ( dbHostName );
127 pDatabase->setPort ( params.
m_dbPort );
130 pDatabase->setName ( params.
m_dbName );
131 pDatabase->setType ( params.
m_dbType );
142 pVersion->setProtocol ( MYTH_PROTO_VERSION );
143 pVersion->setBinary ( MYTH_BINARY_VERSION );
144 pVersion->setSchema ( MYTH_DATABASE_VERSION );
158 bool bResult =
false;
160 QString db(
"mythconverg");
170 throw( QString(
"Database test failed. Not saving database connection information." ));
185 bResult =
GetMythDB()->SaveDatabaseParams(dbparms,
false);
197 throw( QString(
"No MythCoreContext in GetHostName." ));
211 throw( QString(
"Database not open while trying to load list of hosts" ));
214 "SELECT DISTINCTROW hostname "
216 "WHERE (not isNull( hostname ))");
222 throw( QString(
"Database Error executing query." ));
232 oList.append( query.
value(0).toString() );
246 throw( QString(
"Database not open while trying to load settings"));
248 query.
prepare(
"SELECT DISTINCTROW value FROM settings;" );
254 throw( QString(
"Database Error executing query." ));
261 QStringList oResults;
266 oResults.append( query.
value(0).toString() );
277 QDir directory(DirName);
278 QDir::Filters filts = QDir::AllDirs|QDir::NoDotAndDotDot;
282 filts = QDir::AllDirs|QDir::NoDotAndDotDot;
283 return directory.entryList(filts, QDir::Name);
291 const QString &sHostName )
296 throw( QString(
"Database not open while trying to list "
297 "Storage Group Dirs"));
299 if (!sGroupName.isEmpty() && !sHostName.isEmpty())
301 query.
prepare(
"SELECT id, groupname, hostname, dirname "
303 "WHERE groupname = :GROUP AND hostname = :HOST "
304 "ORDER BY groupname, hostname, dirname" );
308 else if (!sHostName.isEmpty())
310 query.
prepare(
"SELECT id, groupname, hostname, dirname "
312 "WHERE hostname = :HOST "
313 "ORDER BY groupname, hostname, dirname" );
316 else if (!sGroupName.isEmpty())
318 query.
prepare(
"SELECT id, groupname, hostname, dirname "
320 "WHERE groupname = :GROUP "
321 "ORDER BY groupname, hostname, dirname" );
326 query.
prepare(
"SELECT id, groupname, hostname, dirname "
328 "ORDER BY groupname, hostname, dirname" );
335 throw( QString(
"Database Error executing query." ));
347 QFileInfo fi(query.
value(3).toString());
350 pStorageGroupDir->setId ( query.
value(0).toInt() );
351 pStorageGroupDir->setGroupName ( query.
value(1).toString() );
352 pStorageGroupDir->setHostName ( query.
value(2).toString() );
353 pStorageGroupDir->setDirName ( query.
value(3).toString() );
354 pStorageGroupDir->setDirRead ( fi.isReadable() );
355 pStorageGroupDir->setDirWrite ( fi.isWritable() );
356 pStorageGroupDir->setKiBFree ( fsInfo.getFreeSpace() );
367 const QString &sDirName,
368 const QString &sHostName )
373 throw( QString(
"Database not open while trying to add Storage Group "
376 if (sGroupName.isEmpty())
377 throw ( QString(
"Storage Group Required" ));
379 if (sDirName.isEmpty())
380 throw ( QString(
"Directory Name Required" ));
382 if (sHostName.isEmpty())
383 throw ( QString(
"HostName Required" ));
385 query.
prepare(
"SELECT COUNT(*) "
387 "WHERE groupname = :GROUPNAME "
388 "AND dirname = :DIRNAME "
389 "AND hostname = :HOSTNAME;");
390 query.
bindValue(
":GROUPNAME", sGroupName );
392 query.
bindValue(
":HOSTNAME" , sHostName );
397 throw( QString(
"Database Error executing query." ));
402 if (query.
value(0).toInt() > 0)
406 query.
prepare(
"INSERT storagegroup "
407 "( groupname, dirname, hostname ) "
409 "( :GROUPNAME, :DIRNAME, :HOSTNAME );");
410 query.
bindValue(
":GROUPNAME", sGroupName );
412 query.
bindValue(
":HOSTNAME" , sHostName );
418 throw( QString(
"Database Error executing query." ));
429 const QString &sDirName,
430 const QString &sHostName )
435 throw( QString(
"Database not open while trying to remove Storage "
438 if (sGroupName.isEmpty())
439 throw ( QString(
"Storage Group Required" ));
441 if (sDirName.isEmpty())
442 throw ( QString(
"Directory Name Required" ));
444 if (sHostName.isEmpty())
445 throw ( QString(
"HostName Required" ));
449 "WHERE groupname = :GROUPNAME "
450 "AND dirname = :DIRNAME "
451 "AND hostname = :HOSTNAME;");
452 query.
bindValue(
":GROUPNAME", sGroupName );
454 query.
bindValue(
":HOSTNAME" , sHostName );
459 throw( QString(
"Database Error executing query." ));
523 if (!dateTime.isValid())
524 throw QString(
"Unable to parse DateTime" );
534 const QString &Application,
537 const QString &Thread,
538 const QString &Filename,
540 const QString &Function,
541 const QDateTime &FromTime,
542 const QDateTime &ToTime,
543 const QString &Level,
544 const QString &MsgContains )
551 QString sql =
"SELECT DISTINCT host FROM logging ORDER BY host ASC";
552 if (!query.
exec(sql))
556 throw( QString(
"Database Error executing query." ));
561 QString availableHostName = query.
value(0).toString();
562 pLabelValue->setValue ( availableHostName );
563 pLabelValue->setActive ( availableHostName == HostName );
564 pLabelValue->setSelected( availableHostName == HostName );
567 sql =
"SELECT DISTINCT application FROM logging ORDER BY application ASC";
568 if (!query.
exec(sql))
572 throw( QString(
"Database Error executing query." ));
577 QString availableApplication = query.
value(0).toString();
578 pLabelValue->setValue ( availableApplication );
579 pLabelValue->setActive ( availableApplication == Application );
580 pLabelValue->setSelected( availableApplication == Application );
583 if (!HostName.isEmpty() && !Application.isEmpty())
586 sql =
"SELECT host, application, pid, tid, thread, filename, "
587 " line, function, msgtime, level, message "
589 " WHERE host = COALESCE(:HOSTNAME, host) "
590 " AND application = COALESCE(:APPLICATION, application) "
591 " AND pid = COALESCE(:PID, pid) "
592 " AND tid = COALESCE(:TID, tid) "
593 " AND thread = COALESCE(:THREAD, thread) "
594 " AND filename = COALESCE(:FILENAME, filename) "
595 " AND line = COALESCE(:LINE, line) "
596 " AND function = COALESCE(:FUNCTION, function) "
597 " AND msgtime >= COALESCE(:FROMTIME, msgtime) "
598 " AND msgtime <= COALESCE(:TOTIME, msgtime) "
599 " AND level <= COALESCE(:LEVEL, level) "
601 if (!MsgContains.isEmpty())
603 sql.append(
" AND message LIKE :MSGCONTAINS ");
605 sql.append(
" ORDER BY msgtime ASC;");
607#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
608 QVariant ullNull = QVariant(QVariant::ULongLong);
610 QVariant ullNull = QVariant(QMetaType(QMetaType::ULongLong));
614 query.
bindValue(
":HOSTNAME", (HostName.isEmpty()) ? QString() : HostName);
615 query.
bindValue(
":APPLICATION", (Application.isEmpty()) ? QString() :
618 query.
bindValue(
":TID", ( TID == 0 ) ? ullNull : (qint64)TID);
619 query.
bindValue(
":THREAD", (Thread.isEmpty()) ? QString() : Thread);
620 query.
bindValue(
":FILENAME", (Filename.isEmpty()) ? QString() : Filename);
621 query.
bindValue(
":LINE", ( Line == 0 ) ? ullNull : (qint64)Line);
622 query.
bindValue(
":FUNCTION", (Function.isEmpty()) ? QString() : Function);
623 query.
bindValue(
":FROMTIME", (FromTime.isValid()) ? FromTime : QDateTime());
624 query.
bindValue(
":TOTIME", (ToTime.isValid()) ? ToTime : QDateTime());
625 query.
bindValue(
":LEVEL", (Level.isEmpty()) ? ullNull :
628 if (!MsgContains.isEmpty())
630 query.
bindValue(
":MSGCONTAINS",
"%" + MsgContains +
"%" );
637 throw( QString(
"Database Error executing query." ));
644 pLogMessage->setHostName( query.
value(0).toString() );
645 pLogMessage->setApplication( query.
value(1).toString() );
646 pLogMessage->setPID( query.
value(2).toInt() );
647 pLogMessage->setTID( query.
value(3).toInt() );
648 pLogMessage->setThread( query.
value(4).toString() );
649 pLogMessage->setFilename( query.
value(5).toString() );
650 pLogMessage->setLine( query.
value(6).toInt() );
651 pLogMessage->setFunction( query.
value(7).toString() );
654 (LogLevel_t)query.
value(9).toInt()) );
655 pLogMessage->setMessage( query.
value(10).toString() );
681 const QString &sDefault )
684 throw( QString(
"Missing or empty Key (settings.value)") );
686 if (sHostName ==
"_GLOBAL_")
690 query.
prepare(
"SELECT data FROM settings "
691 "WHERE value = :VALUE "
692 "AND (hostname IS NULL)" );
699 throw( QString(
"Database Error executing query." ));
702 return query.
next() ? query.
value(0).toString() : sDefault;
707 if (sHostName.isEmpty())
724 throw( QString(
"Database not open while trying to load settings for host: %1")
730 pList->setHostName ( sHostName );
736 if (sHostName.isEmpty())
738 query.
prepare(
"SELECT value, data FROM settings "
739 "WHERE (hostname IS NULL)" );
743 query.
prepare(
"SELECT value, data FROM settings "
744 "WHERE (hostname = :HOSTNAME)" );
746 query.
bindValue(
":HOSTNAME", sHostName );
756 throw( QString(
"Database Error executing query." ));
760 pList->Settings().insert( query.
value(0).toString(), query.
value(1) );
771 const QString &sValue )
773 QString hostName = sHostName;
775 if (sKey.toLower() ==
"apiauthreqd")
778 "authorization").trimmed();
779 if (authorization.isEmpty())
780 authorization =
m_request->m_queries.value(
"authorization",{});
783 throw QString (
"Forbidden: PutSetting " + sKey);
786 if (hostName ==
"_GLOBAL_")
794 throw ( QString(
"Key Required" ));
804 QString hostName = sHostName;
806 if (hostName ==
"_GLOBAL_")
814 throw ( QString(
"Key Required" ));
823 const QString &sUserName,
824 const QString &sPassword,
825 const QString &sDBName,
828 bool bResult =
false;
830 QString db(
"mythconverg");
833 if (!sDBName.isEmpty())
839 bResult =
TestDatabase(sHostName, sUserName, sPassword, db, port);
849 const QString &sAddress,
853 bool bResult =
false;
855 if (sMessage.isEmpty())
858 if (Timeout < 0 || Timeout > 999)
862 "<mythmessage version=\"1\">\n"
863 " <text>" + sMessage +
"</text>\n"
864 " <timeout>" + QString::number(Timeout) +
"</timeout>\n"
867 QHostAddress address = QHostAddress::Broadcast;
868 unsigned short port = 6948;
870 if (!sAddress.isEmpty())
871 address.setAddress(sAddress);
876 auto *sock =
new QUdpSocket();
877 QByteArray utf8 = xmlMessage.toUtf8();
878 int size = utf8.length();
880 if (sock->writeDatagram(utf8.constData(), size, address, port) < 0)
882 LOG(VB_GENERAL, LOG_ERR,
883 QString(
"Failed to send UDP/XML packet (Message: %1 "
884 "Address: %2 Port: %3")
885 .arg(sMessage, sAddress, QString::number(port)));
889 LOG(VB_GENERAL, LOG_DEBUG,
890 QString(
"UDP/XML packet sent! (Message: %1 Address: %2 Port: %3")
892 address.toString().toLocal8Bit(),
893 QString::number(port)));
904 const QString &sMessage,
905 const QString &sOrigin,
906 const QString &sDescription,
907 const QString &sImage,
908 const QString &sExtra,
909 const QString &sProgressText,
915 const QString &sAddress,
918 bool bResult =
false;
920 if (sMessage.isEmpty())
923 if (Timeout < 0 || Timeout > 999)
927 "<mythnotification version=\"1\">\n"
928 " <text>" + sMessage +
"</text>\n"
929 " <origin>" + (sOrigin.isNull() ? tr(
"MythServices") : sOrigin) +
"</origin>\n"
930 " <description>" + sDescription +
"</description>\n"
931 " <timeout>" + QString::number(Timeout) +
"</timeout>\n"
932 " <image>" + sImage +
"</image>\n"
933 " <extra>" + sExtra +
"</extra>\n"
934 " <progress_text>" + sProgressText +
"</progress_text>\n"
935 " <progress>" + QString::number(fProgress) +
"</progress>\n"
936 " <fullscreen>" + (bFullscreen ?
"true" :
"false") +
"</fullscreen>\n"
937 " <visibility>" + QString::number(Visibility) +
"</visibility>\n"
938 " <priority>" + QString::number(
Priority) +
"</priority>\n"
939 " <type>" + (bError ?
"error" : Type) +
"</type>\n"
940 "</mythnotification>";
942 QHostAddress address = QHostAddress::Broadcast;
943 unsigned short port = 6948;
945 if (!sAddress.isEmpty())
946 address.setAddress(sAddress);
951 auto *sock =
new QUdpSocket();
952 QByteArray utf8 = xmlMessage.toUtf8();
953 int size = utf8.length();
955 if (sock->writeDatagram(utf8.constData(), size, address, port) < 0)
957 LOG(VB_GENERAL, LOG_ERR,
958 QString(
"Failed to send UDP/XML packet (Notification: %1 "
959 "Address: %2 Port: %3")
960 .arg(sMessage, sAddress, QString::number(port)));
964 LOG(VB_GENERAL, LOG_DEBUG,
965 QString(
"UDP/XML packet sent! (Notification: %1 Address: %2 Port: %3")
967 address.toString().toLocal8Bit(), QString::number(port)));
982 bool bResult =
false;
988 LOG(VB_GENERAL, LOG_NOTICE,
"Performing API invoked DB Backup.");
994 LOG(VB_GENERAL, LOG_NOTICE,
"Database backup succeeded.");
999 LOG(VB_GENERAL, LOG_ERR,
"Database backup failed.");
1011 LOG(VB_GENERAL, LOG_NOTICE,
"Performing API invoked DB Check.");
1016 LOG(VB_GENERAL, LOG_NOTICE,
"Database check complete.");
1018 LOG(VB_GENERAL, LOG_ERR,
"Database check failed.");
1026 if (scheduler ==
nullptr)
1029 LOG(VB_GENERAL, LOG_NOTICE,
"Shutdown delayed 5 minutes for external application.");
1040 LOG(VB_GENERAL, LOG_NOTICE,
"Profile Submission...");
1042 bool bResult =
profile.SubmitProfile();
1044 LOG(VB_GENERAL, LOG_NOTICE,
"Profile Submitted.");
1056 LOG(VB_GENERAL, LOG_NOTICE,
"Profile Deletion...");
1058 bool bResult =
profile.DeleteProfile();
1060 LOG(VB_GENERAL, LOG_NOTICE,
"Profile Deleted.");
1071 QString sProfileURL;
1075 sProfileURL =
profile.GetProfileURL();
1076 LOG(VB_GENERAL, LOG_NOTICE, QString(
"ProfileURL: %1").arg(sProfileURL));
1087 QString sProfileUpdate;
1092 tUpdated =
profile.GetLastUpdate();
1093 sProfileUpdate = tUpdated.toString(
1096 return sProfileUpdate;
1105 QString sProfileText;
1110 return sProfileText;
1130 pBuild->setLibX264 ( CONFIG_LIBX264 );
1131 pBuild->setLibDNS_SD ( CONFIG_LIBDNS_SD );
1132 pEnv->setLANG ( qEnvironmentVariable(
"LANG") );
1133 pEnv->setLCALL ( qEnvironmentVariable(
"LC_ALL") );
1134 pEnv->setLCCTYPE ( qEnvironmentVariable(
"LC_CTYPE") );
1135 pEnv->setHOME ( qEnvironmentVariable(
"HOME") );
1136 pEnv->setHttpRootDir (
m_request->m_root );
1138 pEnv->setUSER ( qEnvironmentVariable(
"USER",
1139 qEnvironmentVariable(
"USERNAME")) );
1140 pEnv->setMYTHCONFDIR ( qEnvironmentVariable(
"MYTHCONFDIR") );
1142 if (scheduler !=
nullptr)
1143 pEnv->setSchedulingEnabled(scheduler->QueryScheduling());
1153 webOnly =
"DBSETUP";
1156 webOnly =
"DBTIMEZONE";
1159 webOnly =
"WEBONLYPARM";
1162 webOnly =
"IPADDRESS";
1165 webOnly =
"SCHEMAUPDATE";
1168 pEnv->setWebOnlyStartup (webOnly);
1183 const QString &sUserName,
1184 const QString &sPassword,
1185 const QString &sNewPassword)
1189 QString loggedInUser;
1192 "authorization").trimmed();
1193 if (authorization.isEmpty())
1194 authorization =
m_request->m_queries.value(
"authorization",{});
1201 if (sAction ==
"Add")
1205 else if (sAction ==
"Remove")
1209 else if (sAction ==
"ChangePassword")
1212 if (sPassword.isEmpty() && loggedInUser !=
"admin" && !loggedInUser.isEmpty())
1214 throw QString (
"Forbidden: ManageDigestUser "
1215 + loggedInUser +
" Old Password required");
1220 LOG(VB_GENERAL, LOG_ERR, QString(
"Action must be Add, Remove or "
1221 "ChangePassword, not '%1'")
1226 if (!loggedInUser.isEmpty()
1227 && loggedInUser !=
"admin" && loggedInUser != sUserName)
1229 throw QString (
"Forbidden: ManageDigestUser " + sessionManager->
GetSession(authorization).
GetUserName());
1233 sPassword, sNewPassword);
1242 const QString &Client )
1257 if (result.isEmpty())
1267 throw( QString(
"Database not open while trying to load list of users" ));
1277 throw( QString(
"Database Error executing query." ));
1286 while (query.
next())
1287 oList.append( query.
value(0).toString() );
1297 const QString &sAdminPassword )
1299 LOG(VB_GENERAL, LOG_WARNING, QString(
"ManageUrlProtection is deprecated."
1300 "Protection unavailable in API V2."));
1304 LOG(VB_GENERAL, LOG_ERR, QString(
"Backend has no '%1' user!")
1312 LOG(VB_GENERAL, LOG_ERR, QString(
"Incorrect password for user: %1")
1317 QStringList serviceList = sServices.split(
",");
1319 serviceList.removeDuplicates();
1321 QStringList protectedURLs;
1323 if (serviceList.size() == 1 && serviceList.first() ==
"All")
1326 protectedURLs <<
'/' + service;
1328 else if (serviceList.size() == 1 && serviceList.first() ==
"None")
1330 protectedURLs <<
"Unprotected";
1334 for (
const QString& service : std::as_const(serviceList))
1337 protectedURLs <<
'/' + service;
1339 LOG(VB_GENERAL, LOG_ERR, QString(
"Invalid service name: '%1'")
1344 if (protectedURLs.isEmpty())
1346 LOG(VB_GENERAL, LOG_ERR,
"No valid Services were found");
1351 protectedURLs.join(
';'),
"");
1357 if (scheduler ==
nullptr)
1358 throw QString(
"Scheduler is null");
1360 if (Enable == Disable)
1364 scheduler->EnableScheduling();
1368 scheduler->DisableScheduling();
1369 api_sd_notify(
"STATUS=Scheduling disabled via Services API/Web App.");
1373 tvrec->EnableActiveScan(Enable);
1379 if (Retcode < 0 || Retcode > 255)
1397 QCoreApplication::exit(Retcode);
1403 QUrl url(urlString);
1407 auto *req =
new QNetworkRequest(url);
1408 req->setHeader(QNetworkRequest::ContentTypeHeader, QString(
"application/x-www-form-urlencoded"));
Aggregates database and DBMS utility functions.
static MythDBBackupStatus BackupDB(QString &filename, bool disableRotation=false)
Requests a backup of the database.
static bool CheckTables(bool repair=false, const QString &options="QUICK")
Checks database tables.
static bool CheckTimeZoneSupport(void)
Check if MySQL has working timz zone support.
Structure containing the basic Database parameters.
QString m_dbName
database name
QString m_dbPassword
DB password.
std::chrono::seconds m_wolReconnect
seconds to wait for reconnect
QString m_localHostName
name used for loading/saving settings
bool m_localEnabled
true if localHostName is not default
bool m_dbHostPing
No longer used.
QString m_dbUserName
DB user name.
QString m_dbType
database type (MySQL, Postgres, etc.)
QString m_wolCommand
command to use for wake-on-lan
bool m_wolEnabled
true if wake-on-lan params are used
int m_dbPort
database port
int m_wolRetry
times to retry to reconnect
QString m_dbHostName
database server
static QString GetHardwareProfile(void)
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
bool isConnected(void) const
Only updated once during object creation.
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
QString GetHostName(void)
MythScheduler * GetScheduler(void)
MythSessionManager * GetSessionManager(void)
QString GetSetting(const QString &key, const QString &defaultval="")
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
QString GetSettingOnHost(const QString &key, const QString &host, const QString &defaultval="")
QString GetBackendServerIP(void)
Returns the IP address of the locally defined backend IP.
static void DBError(const QString &where, const MSqlQuery &query)
bool HAS_PARAMv2(const QString &p)
static QString GetHeader(const HTTPHeaders &Headers, const QString &Value, const QString &Default="")
We use digest authentication because it protects the password over unprotected networks.
static bool IsValidUser(const QString &username)
Check if the given user exists but not whether there is a valid session open for them!
static QString GetPasswordDigest(const QString &username)
Load the password digest for comparison in the HTTP Auth code.
MythUserSession GetSession(const QString &sessionToken)
Load the session details and return.
static QByteArray CreateDigest(const QString &username, const QString &password)
Generate a digest string.
bool ManageDigestUser(DigestUserActions action, const QString &username, const QString &password, const QString &newPassword)
Manage digest user entries.
MythUserSession LoginUser(const QString &username, const QByteArray &digest, const QString &client="")
Login user by digest.
QString GetSessionToken(void) const
QString GetUserName(void) const
Contains Packet Identifier numeric values.
static QMap< uint, TVRec * > s_inputs
static QStringList GetKeys()
static V2TimeZoneInfo * GetTimeZone()
static bool RemoveStorageGroupDir(const QString &GroupName, const QString &DirName, const QString &HostName)
static V2SettingList * GetSettingList(const QString &HostName)
bool PutSetting(const QString &HostName, const QString &Key, const QString &Value)
static bool AddStorageGroupDir(const QString &GroupName, const QString &DirName, const QString &HostName)
static 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 Timeout, bool Fullscreen, uint Visibility, uint Priority, const QString &Address, int udpPort)
static bool DelayShutdown(void)
static bool TestDBSettings(const QString &HostName, const QString &UserName, const QString &Password, const QString &DBName, int dbPort)
static void RegisterCustomTypes()
static WebOnlyStartup s_WebOnlyStartup
static V2LogMessageList * 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)
static QString GetHostName()
static QString GetSetting(const QString &HostName, const QString &Key, const QString &Default)
QString LoginUser(const QString &UserName, const QString &Password, const QString &Client)
static bool BackupDatabase(void)
static bool SendMessage(const QString &Message, const QString &Address, int udpPort, int Timeout)
static bool ProfileSubmit(void)
static bool CheckDatabase(bool Repair)
static V2FrontendList * GetFrontends(bool OnLine)
static V2StorageGroupDirList * GetStorageGroupDirs(const QString &GroupName, const QString &HostName)
static QStringList GetUsers(void)
static QString ProfileText(void)
bool ManageDigestUser(const QString &Action, const QString &UserName, const QString &Password, const QString &NewPassword)
static QString GetFormatTime(const QDateTime &Time)
V2BackendInfo * GetBackendInfo(void)
static bool SetConnectionInfo(const QString &Host, const QString &UserName, const QString &Password, const QString &Name, int Port, bool DoTest)
static QString Proxy(const QString &Url)
static QStringList GetDirListing(const QString &DirName, bool Files)
static bool ProfileDelete(void)
static bool DeleteSetting(const QString &HostName, const QString &Key)
static bool ManageUrlProtection(const QString &Services, const QString &AdminPassword)
static QStringList GetHosts()
static bool Shutdown(int Retcode, bool Restart, bool WebOnly)
static QString GetFormatDate(const QDateTime &Date, bool ShortDate)
static bool ManageScheduler(bool Enable, bool Disable)
static QDateTime ParseISODateString(const QString &DateTime)
static QString ProfileUpdated(void)
static QString GetFormatDateTime(const QDateTime &DateTime, bool ShortDate)
static QString ProfileURL(void)
static V2ConnectionInfo * GetConnectionInfo(const QString &Pin)
static StandardSetting * Password(bool enabled)
Setting for changing password.
QString logLevelGetName(LogLevel_t level)
Map a log level enumerated value back to the name.
LogLevel_t logLevelGet(const QString &level)
Map a log level name back to the enumerated value.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
bool TestDatabase(const QString &dbHostName, const QString &dbUserName, QString dbPassword, QString dbName, int dbPort)
MythDownloadManager * GetMythDownloadManager(void)
Gets the pointer to the MythDownloadManager singleton.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
const char * GetMythSourceVersion()
const char * GetMythSourcePath()
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
@ kDateTimeFull
Default local time.
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
@ kDateFull
Default local time.
@ kDateTimeShort
Default local time.
@ kTime
Default local time.
@ kDateShort
Default local time.
@ kAutoYear
Add year only if different from current year.
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
int calc_utc_offset(void)
QString getTimeZoneID(void)
Returns the zoneinfo time zone ID or as much time zone information as possible.
static void api_sd_notify(const char *)
Q_GLOBAL_STATIC_WITH_ARGS(MythHTTPMetaService, s_service,(MYTH_HANDLE, V2Myth::staticMetaObject, &V2Myth::RegisterCustomTypes)) void V2Myth
void FillFrontendList(QVariantList &list, QObject *parent, bool OnLine)
const QStringList KnownServicesV2