Ticket #8262: 8262-v3.patch
| File 8262-v3.patch, 99.9 KB (added by danielk, 18 months ago) |
|---|
-
mythtv/libs/libmyth/mythcontext.cpp
71 71 72 72 void LoadDatabaseSettings(void); 73 73 74 bool LoadSettingsFile(void);75 bool WriteSettingsFile(const DatabaseParams ¶ms,76 bool overwrite = false);77 bool FindSettingsProbs(void);78 79 74 bool PromptForDatabaseParams(const QString &error); 80 75 QString TestDBconnection(void); 81 76 void SilenceDBerrors(void); … … 464 459 */ 465 460 void MythContextPrivate::LoadDatabaseSettings(void) 466 461 { 467 if (!LoadSettingsFile()) 468 { 469 VERBOSE(VB_IMPORTANT, "Unable to read configuration file mysql.txt"); 462 gCoreContext->GetDB()->LoadDatabaseParamsFromDisk(m_DBparams, true); 463 gCoreContext->GetDB()->SetDatabaseParams(m_DBparams); 470 464 471 // Sensible connection defaults.472 m_DBparams.dbHostName = "localhost";473 m_DBparams.dbHostPing = true;474 m_DBparams.dbPort = 0;475 m_DBparams.dbUserName = "mythtv";476 m_DBparams.dbPassword = "mythtv";477 m_DBparams.dbName = "mythconverg";478 m_DBparams.dbType = "QMYSQL3";479 m_DBparams.localEnabled = false;480 m_DBparams.localHostName = "my-unique-identifier-goes-here";481 m_DBparams.wolEnabled = false;482 m_DBparams.wolReconnect = 0;483 m_DBparams.wolRetry = 5;484 m_DBparams.wolCommand = "echo 'WOLsqlServerCommand not set'";485 gCoreContext->GetDB()->SetDatabaseParams(m_DBparams);486 }487 488 // Even if we have loaded the settings file, it may be incomplete,489 // so we check for missing values and warn user490 FindSettingsProbs();491 492 465 QString hostname = m_DBparams.localHostName; 493 466 if (hostname.isEmpty() || 494 467 hostname == "my-unique-identifier-goes-here") … … 509 482 gCoreContext->SetLocalHostname(hostname); 510 483 } 511 484 512 /**513 * Load mysql.txt and parse its values into m_DBparams514 */515 bool MythContextPrivate::LoadSettingsFile(void)516 {517 Settings *oldsettings = gCoreContext->GetDB()->GetOldSettings();518 519 if (!oldsettings->LoadSettingsFiles("mysql.txt", GetInstallPrefix(),520 GetConfDir()))521 return false;522 523 m_DBparams.dbHostName = oldsettings->GetSetting("DBHostName");524 m_DBparams.dbHostPing = oldsettings->GetSetting("DBHostPing") != "no";525 m_DBparams.dbPort = oldsettings->GetNumSetting("DBPort");526 m_DBparams.dbUserName = oldsettings->GetSetting("DBUserName");527 m_DBparams.dbPassword = oldsettings->GetSetting("DBPassword");528 m_DBparams.dbName = oldsettings->GetSetting("DBName");529 m_DBparams.dbType = oldsettings->GetSetting("DBType");530 531 m_DBparams.localHostName = oldsettings->GetSetting("LocalHostName");532 m_DBparams.localEnabled = m_DBparams.localHostName.length() > 0;533 534 m_DBparams.wolReconnect535 = oldsettings->GetNumSetting("WOLsqlReconnectWaitTime");536 m_DBparams.wolEnabled = m_DBparams.wolReconnect > 0;537 538 m_DBparams.wolRetry = oldsettings->GetNumSetting("WOLsqlConnectRetry");539 m_DBparams.wolCommand = oldsettings->GetSetting("WOLsqlCommand");540 gCoreContext->GetDB()->SetDatabaseParams(m_DBparams);541 542 return true;543 }544 545 bool MythContextPrivate::WriteSettingsFile(const DatabaseParams ¶ms,546 bool overwrite)547 {548 QString path = GetConfDir() + "/mysql.txt";549 QFile * f = new QFile(path);550 551 if (!overwrite && f->exists())552 {553 delete f;554 return false;555 }556 557 QString dirpath = GetConfDir();558 QDir createDir(dirpath);559 560 if (!createDir.exists())561 {562 if (!createDir.mkdir(dirpath))563 {564 VERBOSE(VB_IMPORTANT, QString("Could not create %1").arg(dirpath));565 return false;566 }567 }568 569 if (!f->open(QIODevice::WriteOnly))570 {571 VERBOSE(VB_IMPORTANT, QString("Could not open settings file %1 "572 "for writing").arg(path));573 return false;574 }575 576 VERBOSE(VB_IMPORTANT, QString("Writing settings file %1").arg(path));577 QTextStream s(f);578 s << "DBHostName=" << params.dbHostName << endl;579 580 s << "\n"581 << "# By default, MythTV tries to ping the DB host to see if it exists.\n"582 << "# If your DB host or network doesn't accept pings, set this to no:\n"583 << "#\n";584 585 if (params.dbHostPing)586 s << "#DBHostPing=no" << endl << endl;587 else588 s << "DBHostPing=no" << endl << endl;589 590 if (params.dbPort)591 s << "DBPort=" << params.dbPort << endl;592 593 s << "DBUserName=" << params.dbUserName << endl594 << "DBPassword=" << params.dbPassword << endl595 << "DBName=" << params.dbName << endl596 << "DBType=" << params.dbType << endl597 << endl598 << "# Set the following if you want to use something other than this\n"599 << "# machine's real hostname for identifying settings in the database.\n"600 << "# This is useful if your hostname changes often, as otherwise you\n"601 << "# will need to reconfigure mythtv every time.\n"602 << "# NO TWO HOSTS MAY USE THE SAME VALUE\n"603 << "#\n";604 605 if (params.localEnabled)606 s << "LocalHostName=" << params.localHostName << endl;607 else608 s << "#LocalHostName=my-unique-identifier-goes-here\n";609 610 s << endl611 << "# If you want your frontend to be able to wake your MySQL server\n"612 << "# using WakeOnLan, have a look at the following settings:\n"613 << "#\n"614 << "#\n"615 << "# The time the frontend waits (in seconds) between reconnect tries.\n"616 << "# This should be the rough time your MySQL server needs for startup\n"617 << "#\n";618 619 if (params.wolEnabled)620 s << "WOLsqlReconnectWaitTime=" << params.wolReconnect << endl;621 else622 s << "#WOLsqlReconnectWaitTime=0\n";623 624 s << "#\n"625 << "#\n"626 << "# This is the number of retries to wake the MySQL server\n"627 << "# until the frontend gives up\n"628 << "#\n";629 630 if (params.wolEnabled)631 s << "WOLsqlConnectRetry=" << params.wolRetry << endl;632 else633 s << "#WOLsqlConnectRetry=5\n";634 635 s << "#\n"636 << "#\n"637 << "# This is the command executed to wake your MySQL server.\n"638 << "#\n";639 640 if (params.wolEnabled)641 s << "WOLsqlCommand=" << params.wolCommand << endl;642 else643 s << "#WOLsqlCommand=echo 'WOLsqlServerCommand not set'\n";644 645 f->close();646 return true;647 }648 649 bool MythContextPrivate::FindSettingsProbs(void)650 {651 bool problems = false;652 653 if (m_DBparams.dbHostName.isEmpty())654 {655 problems = true;656 VERBOSE(VB_IMPORTANT, "DBHostName is not set in mysql.txt");657 VERBOSE(VB_IMPORTANT, "Assuming localhost");658 m_DBparams.dbHostName = "localhost";659 }660 if (m_DBparams.dbUserName.isEmpty())661 {662 problems = true;663 VERBOSE(VB_IMPORTANT, "DBUserName is not set in mysql.txt");664 }665 if (m_DBparams.dbPassword.isEmpty())666 {667 problems = true;668 VERBOSE(VB_IMPORTANT, "DBPassword is not set in mysql.txt");669 }670 if (m_DBparams.dbName.isEmpty())671 {672 problems = true;673 VERBOSE(VB_IMPORTANT, "DBName is not set in mysql.txt");674 }675 gCoreContext->GetDB()->SetDatabaseParams(m_DBparams);676 return problems;677 }678 679 485 bool MythContextPrivate::PromptForDatabaseParams(const QString &error) 680 486 { 681 487 bool accepted = false; … … 974 780 switch (selected) 975 781 { 976 782 case kDialogCodeButton0: 977 if (!WriteSettingsFile(m_DBparams, true)) 978 { 979 VERBOSE(VB_IMPORTANT, "WriteSettingsFile failed."); 980 return -1; 981 } 783 MythDB::SaveDatabaseParamsToDisk(m_DBparams, GetConfDir(), true); 982 784 // User prefers mysql.txt, so throw away default UPnP backend: 983 785 m_XML->SetValue(kDefaultUSN, ""); 984 786 m_XML->Save(); … … 1470 1272 params.wolRetry != cur_params.wolRetry || 1471 1273 params.wolCommand != cur_params.wolCommand))) 1472 1274 { 1473 ret = d->WriteSettingsFile(params, true);1275 ret = MythDB::SaveDatabaseParamsToDisk(params, GetConfDir(), true); 1474 1276 if (ret) 1475 1277 { 1476 1278 // Save the new settings: -
mythtv/libs/libmythupnp/httprequest.cpp
846 846 { 847 847 sName = QUrl::fromPercentEncoding(sName.toLatin1()); 848 848 sValue = QUrl::fromPercentEncoding(sValue.toLatin1()); 849 sValue.replace("+"," "); 849 850 850 851 mapParams.insert( sName.trimmed(), sValue ); 851 852 nCount++; -
mythtv/libs/libmythdb/mythdb.cpp
1 1 #include <vector> 2 2 using namespace std; 3 3 4 #include <QReadWriteLock> 5 #include <QSqlError> 4 6 #include <QMutex> 5 #include <Q ReadWriteLock>7 #include <QFile> 6 8 #include <QHash> 7 #include <Q SqlError>9 #include <QDir> 8 10 9 11 #include "mythdb.h" 10 12 #include "mythdbcon.h" 11 13 #include "mythverbose.h" 12 14 #include "oldsettings.h" 15 #include "mythdirs.h" 13 16 14 17 static MythDB *mythdb = NULL; 15 18 static QMutex dbLock; … … 845 848 ClearSettingsCache(); 846 849 } 847 850 851 bool MythDB::LoadDatabaseParamsFromDisk( 852 DatabaseParams ¶ms, bool sanitize) 853 { 854 Settings settings; 855 if (settings.LoadSettingsFiles( 856 "mysql.txt", GetInstallPrefix(), GetConfDir())) 857 { 858 params.dbHostName = settings.GetSetting("DBHostName"); 859 params.dbHostPing = settings.GetSetting("DBHostPing") != "no"; 860 params.dbPort = settings.GetNumSetting("DBPort"); 861 params.dbUserName = settings.GetSetting("DBUserName"); 862 params.dbPassword = settings.GetSetting("DBPassword"); 863 params.dbName = settings.GetSetting("DBName"); 864 params.dbType = settings.GetSetting("DBType"); 865 866 params.localHostName = settings.GetSetting("LocalHostName"); 867 params.localEnabled = !params.localHostName.isEmpty(); 868 869 params.wolReconnect = 870 settings.GetNumSetting("WOLsqlReconnectWaitTime"); 871 params.wolEnabled = params.wolReconnect > 0; 872 873 params.wolRetry = settings.GetNumSetting("WOLsqlConnectRetry"); 874 params.wolCommand = settings.GetSetting("WOLsqlCommand"); 875 } 876 else if (sanitize) 877 { 878 VERBOSE(VB_IMPORTANT, "Unable to read configuration file mysql.txt"); 879 880 // Sensible connection defaults. 881 params.dbHostName = "localhost"; 882 params.dbHostPing = true; 883 params.dbPort = 0; 884 params.dbUserName = "mythtv"; 885 params.dbPassword = "mythtv"; 886 params.dbName = "mythconverg"; 887 params.dbType = "QMYSQL3"; 888 params.localEnabled = false; 889 params.localHostName = "my-unique-identifier-goes-here"; 890 params.wolEnabled = false; 891 params.wolReconnect = 0; 892 params.wolRetry = 5; 893 params.wolCommand = "echo 'WOLsqlServerCommand not set'"; 894 } 895 else 896 { 897 return false; 898 } 899 900 // Print some warnings if things look fishy.. 901 902 if (params.dbHostName.isEmpty()) 903 { 904 VERBOSE(VB_IMPORTANT, "DBHostName is not set in mysql.txt"); 905 VERBOSE(VB_IMPORTANT, "Assuming localhost"); 906 } 907 if (params.dbUserName.isEmpty()) 908 VERBOSE(VB_IMPORTANT, "DBUserName is not set in mysql.txt"); 909 if (params.dbPassword.isEmpty()) 910 VERBOSE(VB_IMPORTANT, "DBPassword is not set in mysql.txt"); 911 if (params.dbName.isEmpty()) 912 VERBOSE(VB_IMPORTANT, "DBName is not set in mysql.txt"); 913 914 // If sanitize set, replace empty dbHostName with "localhost" 915 if (sanitize && params.dbHostName.isEmpty()) 916 params.dbHostName = "localhost"; 917 918 return true; 919 } 920 921 bool MythDB::SaveDatabaseParamsToDisk( 922 const DatabaseParams ¶ms, const QString &confdir, bool overwrite) 923 { 924 QString path = confdir + "/mysql.txt"; 925 QFile * f = new QFile(path); 926 927 if (!overwrite && f->exists()) 928 { 929 return false; 930 } 931 932 QString dirpath = confdir; 933 QDir createDir(dirpath); 934 935 if (!createDir.exists()) 936 { 937 if (!createDir.mkdir(dirpath)) 938 { 939 VERBOSE(VB_IMPORTANT, QString("Could not create %1").arg(dirpath)); 940 return false; 941 } 942 } 943 944 if (!f->open(QIODevice::WriteOnly)) 945 { 946 VERBOSE(VB_IMPORTANT, QString("Could not open settings file %1 " 947 "for writing").arg(path)); 948 return false; 949 } 950 951 VERBOSE(VB_IMPORTANT, QString("Writing settings file %1").arg(path)); 952 QTextStream s(f); 953 s << "DBHostName=" << params.dbHostName << endl; 954 955 s << "\n" 956 << "# By default, Myth tries to ping the DB host to see if it exists.\n" 957 << "# If your DB host or network doesn't accept pings, set this to no:\n" 958 << "#\n"; 959 960 if (params.dbHostPing) 961 s << "#DBHostPing=no" << endl << endl; 962 else 963 s << "DBHostPing=no" << endl << endl; 964 965 if (params.dbPort) 966 s << "DBPort=" << params.dbPort << endl; 967 968 s << "DBUserName=" << params.dbUserName << endl 969 << "DBPassword=" << params.dbPassword << endl 970 << "DBName=" << params.dbName << endl 971 << "DBType=" << params.dbType << endl 972 << endl 973 << "# Set the following if you want to use something other than this\n" 974 << "# machine's real hostname for identifying settings in the database.\n" 975 << "# This is useful if your hostname changes often, as otherwise you\n" 976 << "# will need to reconfigure mythtv every time.\n" 977 << "# NO TWO HOSTS MAY USE THE SAME VALUE\n" 978 << "#\n"; 979 980 if (params.localEnabled) 981 s << "LocalHostName=" << params.localHostName << endl; 982 else 983 s << "#LocalHostName=my-unique-identifier-goes-here\n"; 984 985 s << endl 986 << "# If you want your frontend to be able to wake your MySQL server\n" 987 << "# using WakeOnLan, have a look at the following settings:\n" 988 << "#\n" 989 << "#\n" 990 << "# The time the frontend waits (in seconds) between reconnect tries.\n" 991 << "# This should be the rough time your MySQL server needs for startup\n" 992 << "#\n"; 993 994 if (params.wolEnabled) 995 s << "WOLsqlReconnectWaitTime=" << params.wolReconnect << endl; 996 else 997 s << "#WOLsqlReconnectWaitTime=0\n"; 998 999 s << "#\n" 1000 << "#\n" 1001 << "# This is the number of retries to wake the MySQL server\n" 1002 << "# until the frontend gives up\n" 1003 << "#\n"; 1004 1005 if (params.wolEnabled) 1006 s << "WOLsqlConnectRetry=" << params.wolRetry << endl; 1007 else 1008 s << "#WOLsqlConnectRetry=5\n"; 1009 1010 s << "#\n" 1011 << "#\n" 1012 << "# This is the command executed to wake your MySQL server.\n" 1013 << "#\n"; 1014 1015 if (params.wolEnabled) 1016 s << "WOLsqlCommand=" << params.wolCommand << endl; 1017 else 1018 s << "#WOLsqlCommand=echo 'WOLsqlServerCommand not set'\n"; 1019 1020 f->close(); 1021 return true; 1022 } 1023 848 1024 void MythDB::WriteDelayedSettings(void) 849 1025 { 850 1026 if (!HaveValidDatabase()) -
mythtv/libs/libmythdb/mythdb.h
82 82 static void destroyMythDB(); 83 83 static QString toCommaList(const QMap<QString, QVariant> &bindings, 84 84 uint indent = 0, uint softMaxColumn = 80); 85 86 static bool LoadDatabaseParamsFromDisk( 87 DatabaseParams ¶ms, bool sanitize); 88 static bool SaveDatabaseParamsToDisk( 89 const DatabaseParams ¶ms, const QString &confdir, bool overwrite); 90 85 91 protected: 86 92 MythDB(); 87 93 ~MythDB(); -
mythtv/programs/mythbackend/backendcontext.h
20 20 extern QString pidfile; 21 21 extern QString logfile; 22 22 23 class BackendContext 24 { 25 26 }; 27 23 28 #endif // _BACKEND_CONTEXT_H_ -
mythtv/programs/mythbackend/mediaserver.cpp
9 9 ////////////////////////////////////////////////////////////////////////////// 10 10 11 11 #include "mediaserver.h" 12 #include "httpconfig.h" 12 13 #include "mythxml.h" 13 14 #include "mythdirs.h" 14 15 … … 29 30 // 30 31 ////////////////////////////////////////////////////////////////////////////// 31 32 32 MediaServer::MediaServer( bool bIsMaster, bool bDisableUPnp /* = FALSE */ ) 33 MediaServer::MediaServer(void) : 34 m_pUPnpCDS(NULL), m_pUPnpCMGR(NULL), upnpMedia(NULL), 35 m_sSharePath(GetShareDir()) 33 36 { 34 VERBOSE(VB_UPNP, QString("MediaServer::Begin"));37 VERBOSE(VB_UPNP, "MediaServer:ctor:Begin"); 35 38 36 39 // ---------------------------------------------------------------------- 37 40 // Initialize Configuration class (Database for Servers) … … 44 47 // ---------------------------------------------------------------------- 45 48 46 49 int nPort = g_pConfig->GetValue( "BackendStatusPort", 6544 ); 47 QString sIP = g_pConfig->GetValue( "BackendServerIP" , "" );48 50 49 if (sIP.isEmpty())50 {51 VERBOSE(VB_IMPORTANT,52 "MediaServer:: No BackendServerIP Address defined");53 m_pHttpServer = NULL;54 return;55 }56 57 58 51 m_pHttpServer = new HttpServer(); 59 52 60 53 if (!m_pHttpServer->listen(QHostAddress::Any, nPort)) … … 66 59 return; 67 60 } 68 61 69 m_sSharePath = GetShareDir();70 62 m_pHttpServer->m_sSharePath = m_sSharePath; 71 63 64 m_pHttpServer->RegisterExtension(new HttpConfig()); 65 66 VERBOSE(VB_UPNP, "MediaServer:ctor:End"); 67 } 68 69 void MediaServer::Init(bool bIsMaster, bool bDisableUPnp /* = FALSE */) 70 { 71 VERBOSE(VB_UPNP, "MediaServer:Init:Begin"); 72 73 int nPort = g_pConfig->GetValue( "BackendStatusPort", 6544 ); 72 74 QString sFileName = g_pConfig->GetValue( "upnpDescXmlPath", 73 75 m_sSharePath ); 74 76 QString sDeviceType; … … 101 103 102 104 VERBOSE(VB_UPNP, "MediaServer::Registering MythXML Service." ); 103 105 104 m_pHttpServer->RegisterExtension( new MythXML( pMythDevice , m_sSharePath)); 106 if (m_pHttpServer) 107 m_pHttpServer->RegisterExtension( 108 new MythXML( pMythDevice , m_sSharePath)); 105 109 110 QString sIP = g_pConfig->GetValue( "BackendServerIP" , "" ); 111 if (sIP.isEmpty()) 112 { 113 VERBOSE(VB_IMPORTANT, 114 "MediaServer:: No BackendServerIP Address defined - " 115 "Disabling UPnP"); 116 return; 117 } 118 106 119 if (sIP == "localhost" || sIP.startsWith("127.")) 107 120 { 108 121 VERBOSE(VB_IMPORTANT, "MediaServer:: Loopback address specified - " … … 190 203 191 204 } 192 205 193 VERBOSE(VB_UPNP, QString( "MediaServer::End" ));206 VERBOSE(VB_UPNP, "MediaServer:Init:End"); 194 207 } 195 208 196 209 ////////////////////////////////////////////////////////////////////////////// -
mythtv/programs/mythbackend/mythsettings.h
1 // -*- Mode: c++ -*- 2 3 #ifndef _MYTHSETTINGS_H_ 4 #define _MYTHSETTINGS_H_ 5 6 #include <QStringList> 7 #include <QMap> 8 9 class MythSettingBase 10 { 11 public: 12 MythSettingBase() {} 13 virtual ~MythSettingBase() {} 14 virtual QString ToHTML(uint) const { return QString(); } 15 }; 16 typedef QList<MythSettingBase*> MythSettingList; 17 18 class MythSettingGroup : public MythSettingBase 19 { 20 public: 21 MythSettingGroup(QString hlabel, QString ulabel, 22 QString script = "") : 23 human_label(hlabel), unique_label(ulabel), ecma_script(script) {} 24 25 QString ToHTML(uint) const; 26 27 public: 28 QString human_label; 29 QString unique_label; ///< div name for stylesheets & javascript 30 MythSettingList settings; 31 QString ecma_script; 32 }; 33 34 class MythSetting : public MythSettingBase 35 { 36 public: 37 typedef enum { 38 kFile, 39 kHost, 40 kGlobal, 41 kInvalidSettingType, 42 } SettingType; 43 44 typedef enum { 45 kInteger, 46 kUnsignedInteger, 47 kIntegerRange, 48 kCheckBox, 49 kSelect, ///< list where only data_list are valid 50 kComboBox, ///< list where user input is allowed 51 kTVFormat, 52 kFrequencyTable, 53 kFloat, 54 kIPAddress, 55 kLocalIPAddress, 56 kString, 57 kTimeOfDay, 58 kOther, 59 kInvalidDataType, 60 } DataType; 61 62 MythSetting(QString _value, QString _default_data, SettingType _stype, 63 QString _label, QString _help_text, DataType _dtype) : 64 value(_value), data(_default_data), default_data(_default_data), 65 stype(_stype), label(_label), help_text(_help_text), dtype(_dtype) 66 { 67 } 68 69 MythSetting(QString _value, QString _default_data, SettingType _stype, 70 QString _label, QString _help_text, DataType _dtype, 71 QStringList _data_list, QStringList _display_list) : 72 value(_value), data(_default_data), default_data(_default_data), 73 stype(_stype), label(_label), help_text(_help_text), dtype(_dtype), 74 data_list(_data_list), display_list(_display_list) 75 { 76 } 77 78 MythSetting(QString _value, QString _default_data, SettingType _stype, 79 QString _label, QString _help_text, DataType _dtype, 80 long long _range_min, long long _range_max) : 81 value(_value), data(_default_data), default_data(_default_data), 82 stype(_stype), label(_label), help_text(_help_text), dtype(_dtype), 83 range_min(_range_min), range_max(_range_max) 84 { 85 } 86 87 MythSetting(QString _value, QString _default_data, SettingType _stype, 88 QString _label, QString _help_text, DataType _dtype, 89 QStringList _data_list, QStringList _display_list, 90 long long _range_min, long long _range_max) : 91 value(_value), data(_default_data), default_data(_default_data), 92 stype(_stype), label(_label), help_text(_help_text), dtype(_dtype), 93 data_list(_data_list), display_list(_display_list), 94 range_min(_range_min), range_max(_range_max) 95 { 96 } 97 98 QString ToHTML(uint) const; 99 100 public: 101 QString value; 102 QString data; 103 QString default_data; 104 SettingType stype; 105 QString label; 106 QString help_text; 107 DataType dtype; 108 QStringList data_list; 109 QStringList display_list; 110 long long range_min; 111 long long range_max; 112 }; 113 114 bool parse_settings(MythSettingList &settings, const QString &filename); 115 bool load_settings(MythSettingList &settings, const QString &hostname); 116 bool check_settings(MythSettingList &database_settings, 117 const QMap<QString,QString> ¶ms); 118 119 #endif -
mythtv/programs/mythbackend/httpconfig.h
1 // -*- Mode: c++ -*- 2 3 #ifndef _HTTPCONFIG_H_ 4 #define _HTTPCONFIG_H_ 5 6 #include "httpserver.h" 7 #include "mythsettings.h" 8 9 class QTextStream; 10 11 class HttpConfig : public HttpServerExtension 12 { 13 public: 14 HttpConfig(); 15 virtual ~HttpConfig(); 16 17 bool ProcessRequest(HttpWorkerThread *pThread, HTTPRequest *pRequest); 18 19 private: 20 static void PrintHeader(QTextStream&, const QString &form); 21 static void PrintFooter(QTextStream&); 22 static bool LoadSettings(MythSettingList&, const QString &hostname); 23 static void PrintSettings(QTextStream&, const MythSettingList&); 24 25 MythSettingList database_settings; 26 MythSettingList general_settings; 27 }; 28 29 #endif -
mythtv/programs/mythbackend/main_helpers.h
1 #ifndef _MAIN_HELPERS_H_2 #define _MAIN_HELPERS_H_3 4 1 // C++ headers 5 2 #include <iostream> 6 3 #include <fstream> … … 16 13 int log_rotate(int report_error); 17 14 void log_rotate_handler(int); 18 15 void upnp_rebuild(int); 19 void showUsage(const MythCommandLineParser &cmdlineparser,20 const QString &version);21 16 void setupLogfile(void); 22 17 bool openPidfile(ofstream &pidfs, const QString &pidfilename); 23 18 bool setUser(const QString &username); … … 48 43 }; 49 44 } 50 45 51 #endif // _MAIN_HELPERS_H_ -
mythtv/programs/mythbackend/main.cpp
1 // POSIX headers2 #include <sys/time.h> // for setpriority3 #include <unistd.h>4 #include <sys/types.h>5 #include <sys/stat.h>6 #include <fcntl.h>7 #include <libgen.h>8 #include <signal.h>9 10 #include "mythconfig.h"11 #if CONFIG_DARWIN12 #include <sys/aio.h> // O_SYNC13 #endif14 15 // C headers16 #include <cstdlib>17 #include <cerrno>18 19 // C++ headers20 #include <iostream>21 #include <fstream>22 using namespace std;23 24 1 #ifndef _WIN32 25 2 #include <QCoreApplication> 26 3 #else 27 4 #include <QApplication> 28 5 #endif 29 6 7 #include <QFileInfo> 8 #include <QRegExp> 9 #include <QThread> 30 10 #include <QFile> 31 #include <QFileInfo>32 11 #include <QDir> 33 12 #include <QMap> 34 #include <QRegExp>35 13 36 #include " tv_rec.h"14 #include "mythcommandlineparser.h" 37 15 #include "scheduledrecording.h" 16 #include "previewgenerator.h" 17 #include "mythcorecontext.h" 18 #include "mythsystemevent.h" 19 #include "backendcontext.h" 20 #include "main_helpers.h" 21 #include "storagegroup.h" 22 #include "housekeeper.h" 23 #include "mediaserver.h" 24 #include "mythverbose.h" 25 #include "mythversion.h" 26 #include "programinfo.h" 38 27 #include "autoexpire.h" 39 #include "scheduler.h"40 28 #include "mainserver.h" 41 29 #include "remoteutil.h" 42 #include "housekeeper.h"43 44 #include "mythcorecontext.h"45 #include "mythverbose.h"46 #include "mythversion.h"47 #include "mythdb.h"48 30 #include "exitcodes.h" 31 #include "scheduler.h" 32 #include "jobqueue.h" 33 #include "dbcheck.h" 49 34 #include "compat.h" 35 #include "mythdb.h" 36 #include "tv_rec.h" 37 38 /* 50 39 #include "storagegroup.h" 51 40 #include "programinfo.h" 52 41 #include "dbcheck.h" 53 42 #include "jobqueue.h" 54 43 #include "mythcommandlineparser.h" 55 44 #include "mythsystemevent.h" 45 .r26134 46 */ 56 47 57 #include "backendcontext.h"58 #include "main_helpers.h"59 60 48 #define LOC QString("MythBackend: ") 61 49 #define LOC_WARN QString("MythBackend, Warning: ") 62 50 #define LOC_ERR QString("MythBackend, Error: ") … … 68 56 #define UNUSED_FILENO 3 69 57 #endif 70 58 59 class MediaServerThread : public QThread 60 { 61 public: 62 void run(void) 63 { 64 g_pUPnp = new MediaServer(); 65 exec(); 66 } 67 68 void BlockUntilReloadNeeded(void) 69 { 70 sleep(60); // TODO 71 } 72 }; 73 71 74 int main(int argc, char **argv) 72 75 { 73 76 bool cmdline_err; … … 182 185 183 186 /////////////////////////////////////////// 184 187 185 return run_backend(cmdline); 188 MediaServerThread *mst = new MediaServerThread(); 189 mst->start(); 190 while (!mst->isRunning()) 191 usleep(25000); 192 while (!g_pUPnp) 193 usleep(25000); 194 195 /////////////////////////////////////////// 196 197 while (true) 198 { 199 exitCode = run_backend(cmdline); 200 mst->BlockUntilReloadNeeded(); 201 } 202 203 return exitCode; 186 204 } 187 205 188 206 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
mythtv/programs/mythbackend/config_backend_general.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <config> 3 <group human_label="Host Address Backend Setup" unique_label="server"> 4 <group human_label="Local Backend" unique_label="local_server"> 5 <setting 6 value="BackendServerIP" default_data="127.0.0.1" 7 setting_type="host" label="IP address" 8 help_text="Enter the IP address of this machine. 9 Use an externally accessible address (ie, not 10 127.0.0.1) if you are going to be running a frontend 11 on a different machine than this one." 12 data_type="localipaddress" /> 13 <setting 14 value="BackendServerPort" default_data="6543" 15 setting_type="host" label="Port" 16 help_text= "Unless you've got good reason to, don't change this." 17 data_type="integer_range" 18 range_min="0" range_max="0xffff" /> 19 <setting 20 value="BackendStatusPort" default_data="6544" 21 setting_type="host" label="Status Port" 22 help_text="Port which the server will listen to for HTTP requests." 23 data_type="integer_range" 24 range_min="0" range_max="0xffff" /> 25 <setting 26 value="SecurityPin" default_data="" 27 setting_type="host" label="Security Pin (Required)" 28 help_text="Pin code required for a frontend to connect 29 to the backend. Blank prevents all connections, 30 0000 allows any client to connect." 31 data_type="string" /> 32 </group> 33 <group human_label="Master Backend" unique_label="master_server"> 34 <setting 35 value="MasterServerIP" default_data="127.0.0.1" 36 setting_type="global" label="IP address" 37 help_text="The IP address of the master backend server. All 38 frontend and non-master backend machines will connect 39 to this server. If you only have one backend, 40 this should be the same IP address as above." 41 data_type="ipaddress" /> 42 <setting 43 value="MasterServerPort" default_data="6543" 44 setting_type="global" label="Port" 45 help_text="Unless you've got good reason to, don't change this." 46 data_type="integer_range" 47 range_min="0" range_max="0xffff" /> 48 </group> 49 <group human_label="Locale Settings" unique_label="locale_settings"> 50 <setting 51 value="TVFormat" default_data="ntsc" 52 setting_type="global" label="TV format" 53 help_text="The TV standard to use for viewing TV." 54 data_type="tvformat" /> 55 <setting value="VbiFormat" default_data="ntsc" 56 setting_type="global" label="VBI format" 57 help_text="VBI stands for Vertical Blanking Interrupt. 58 VBI is used to carry Teletext and 59 Closed Captioning data." 60 data_type="select"> 61 <option display="None" data="none" /> 62 <option display="PAL Teletext" data="pal" /> 63 <option display="NTSC Closed Caption" data="ntsc" /> 64 </setting> 65 <setting value="FreqTable" default_data="us-cable" 66 setting_type="global" label="Channel frequency table" 67 help_text="Select the appropriate frequency table for 68 your system. If you have an antenna, use a 69 '-bcast' frequency." 70 data_type="frequency_table" /> 71 <setting value="TimeOffset" default_data="" 72 setting_type="global" label="Your Local Timezone (for XMLTV)" 73 help_text="Used if the XMLTV data comes from a different 74 timezone than your own. This adjust the times in 75 the XMLTV EPG data to compensate. 'Auto' converts 76 the XMLTV time to local time using your computer's 77 timezone. 'None' ignores the XMLTV timezone, 78 interpreting times as local." 79 data_type="select"> 80 <option display="None" data="none" /> 81 <option display="Auto" data="auto" /> 82 <option display="+0030" data="+0030" /> 83 <option display="+0100" data="+0100" /> 84 <option display="+0130" data="+0130" /> 85 <option display="+0200" data="+0200" /> 86 <option display="+0230" data="+0230" /> 87 <option display="+0300" data="+0300" /> 88 <option display="+0330" data="+0330" /> 89 <option display="+0400" data="+0400" /> 90 <option display="+0430" data="+0430" /> 91 <option display="+0500" data="+0500" /> 92 <option display="+0530" data="+0530" /> 93 <option display="+0600" data="+0600" /> 94 <option display="+0630" data="+0630" /> 95 <option display="+0700" data="+0700" /> 96 <option display="+0730" data="+0730" /> 97 <option display="+0800" data="+0800" /> 98 <option display="+0830" data="+0830" /> 99 <option display="+0900" data="+0900" /> 100 <option display="+0930" data="+0930" /> 101 <option display="+1000" data="+1000" /> 102 <option display="+1030" data="+1030" /> 103 <option display="+1100" data="+1100" /> 104 <option display="+1130" data="+1130" /> 105 <option display="+1200" data="+1200" /> 106 <option display="-1100" data="-1100" /> 107 <option display="-1030" data="-1030" /> 108 <option display="-1000" data="-1000" /> 109 <option display="-0930" data="-0930" /> 110 <option display="-0900" data="-0900" /> 111 <option display="-0830" data="-0830" /> 112 <option display="-0800" data="-0800" /> 113 <option display="-0730" data="-0730" /> 114 <option display="-0700" data="-0700" /> 115 <option display="-0630" data="-0630" /> 116 <option display="-0600" data="-0600" /> 117 <option display="-0530" data="-0530" /> 118 <option display="-0500" data="-0500" /> 119 <option display="-0430" data="-0430" /> 120 <option display="-0400" data="-0400" /> 121 <option display="-0330" data="-0330" /> 122 <option display="-0300" data="-0300" /> 123 <option display="-0230" data="-0230" /> 124 <option display="-0200" data="-0200" /> 125 <option display="-0130" data="-0130" /> 126 <option display="-0100" data="-0100" /> 127 <option display="-0030" data="-0030" /> 128 </setting> 129 </group> 130 <group human_label="Miscellaneous Settings" 131 unique_label="miscellaneous_settings"> 132 <group human_label="File Management Settings" 133 unique_label="file_management_settings"> 134 <setting 135 value="MasterBackendOverride" default_data="1" 136 setting_type="global" label="Master Backend Override" 137 help_text="If enabled, the master backend will stream and 138 delete files if it finds them in the video directory. 139 Useful if you are using a central storage location, like 140 a NFS share, and your slave backend isn't running." 141 data_type="checkbox" /> 142 <setting 143 value="DeletesFollowLinks" default_data="0" 144 setting_type="global" 145 label="Follow symbolic links when deleting files" 146 help_text="This will cause Myth to follow symlinks 147 when recordings and related files are deleted, instead 148 of deleting the symlink and leaving the actual file." 149 data_type="checkbox" /> 150 <setting 151 value="TruncateDeletesSlowly" default_data="0" 152 setting_type="global" label="Delete files slowly" 153 help_text="Some filesystems use a lot of resources when 154 deleting large recording files. This option makes Myth 155 delete the file slowly on this backend to lessen the 156 impact." 157 data_type="checkbox" /> 158 <!-- 159 <setting 160 value="HDRingbufferSize" default_data="9400" 161 setting_type="global" label="HD Ringbuffer size (KB)" 162 help_text="The HD device ringbuffer allows the 163 backend to weather moments of stress. 164 The larger the ringbuffer, the longer 165 the moments of stress can be. However, 166 setting the size too large can cause 167 swapping, which is detrimental." 168 data_type="integer_select" 169 range_min="4700" range_max="94000" step="4700" /> 170 --> 171 <setting 172 value="StorageScheduler" default_data="BalancedFreeSpace" 173 setting_type="global" label="Storage Group Disk Scheduler" 174 help_text="This setting controls how the Storage Group 175 scheduling code will balance new recordings across 176 directories. 'Balanced Free Space' is the recommended 177 method for most users." 178 data_type="select"> 179 <option display="Balanced Free Space" data="BalancedFreeSpace" /> 180 <option display="Balanced Disk I/O" data="BalancedDiskIO" /> 181 <option display="Combination" data="Combination" /> 182 </setting> 183 </group> 184 <setting 185 value="MiscStatusScript" default_data="" 186 setting_type="global" label="Miscellaneous Status Application" 187 help_text="External application or script that outputs 188 extra information for inclusion in the 189 backend status page. See 190 contrib/info/misc_status_info/README" 191 data_type="string" /> 192 <setting 193 value="DisableAutomaticBackup" default_data="0" 194 setting_type="global" label="Disable Automatic Database Backup" 195 help_text="This will prevent Myth from backing up the database 196 before upgrades. If disabled, you should have your 197 own backup strategy in place." 198 data_type="checkbox" /> 199 <setting 200 value="DisableFirewireReset" default_data="0" 201 setting_type="global" label="Disable Firewire Reset" 202 help_text="By default MythTV will reset the firewire bus when a 203 firewire recorder stops responding to commands. But 204 if this causes problems you can disable this here for 205 Linux firewire recorders." 206 data_type="checkbox" /> 207 </group> 208 <group human_label="EIT Scanner Options" 209 unique_label="eit_scanner_options"> 210 <!-- 211 <setting 212 value="EITTransportTimeout" default_data="5" 213 setting_type="global" label="EIT Transport Timeout (mins)" 214 help_text="Maximum time to spend waiting for listings 215 data on one DTV channel before checking for 216 new listings data on the next channel." 217 data_type="integer_select" 218 range_min="1" range_max="15" step="1" /> 219 --> 220 <setting 221 value="EITIgnoresSource" default_data="0" 222 setting_type="global" label="Cross Source EIT" 223 help_text="If enabled, listings data collected on one Video Source 224 will be applied to the first matching DVB channel on 225 any Video Source. This is sometimes useful for DVB-S, 226 but may insert bogus data into any ATSC listings 227 stored in the same database." 228 data_type="checkbox" /> 229 <setting 230 value="EITCrawIdleStart" default_data="60" 231 setting_type="global" 232 label="Backend Idle Before EIT Crawl (seconds)" 233 help_text="The minimum number of seconds after a recorder 234 becomes idle to wait before MythTV begins 235 collecting EIT listings data." 236 data_type="select"> 237 <option display="30" data="30" /> 238 <option display="60" data="60" /> 239 <option display="120" data="120" /> 240 <option display="300" data="300" /> 241 <option display="600" data="600" /> 242 <option display="1200" data="1200" /> 243 <option display="2400" data="2400" /> 244 <option display="3600" data="3600" /> 245 <option display="7200" data="7200" /> 246 </setting> 247 </group> 248 <group human_label="Shutdown/Wakeup Options" 249 unique_label="shutdown_wakeup_options"> 250 <setting data_type="string" value="startupCommand" 251 label="Startup command" 252 default_data="" 253 setting_type="global" 254 help_text="This command is executed right after starting 255 the BE. As a parameter \'$status\' is replaced by either 256 \'auto\' if the machine was started automatically or 257 \'user\' if a user switched it on." /> 258 <setting data_type="checkbox" value="blockSDWUwithoutClient" 259 label="Block shutdown before client connected" 260 default_data="1" 261 setting_type="global" 262 help_text="If set, the automatic shutdown routine will 263 be disabled until a client connects." /> 264 <setting data_type="select" value="idleTimeoutSecs" 265 label="Idle shutdown timeout (secs)" 266 default_data="0" 267 setting_type="global" 268 help_text="The amount of time the master backend idles 269 before it shuts down all backends."> 270 <option display="Disabled" data="0" /> 271 <option display="5" data="5" /> 272 <option display="15" data="15" /> 273 <option display="30" data="30" /> 274 <option display="60" data="60" /> 275 <option display="120" data="120" /> 276 <option display="300" data="300" /> 277 <option display="600" data="600" /> 278 <option display="1200" data="1200" /> 279 </setting> 280 <setting data_type="select" value="idleWaitForRecordingTime" 281 label="Max. wait for recording (min)" 282 default_data="15" 283 setting_type="global" 284 help_text="The amount of time the master backend waits 285 for a recording. If it's idle but a recording starts 286 within this time period, the backends won't shut down."> 287 <option display="5" data="5" /> 288 <option display="15" data="15" /> 289 <option display="30" data="30" /> 290 <option display="60" data="60" /> 291 <option display="120" data="120" /> 292 </setting> 293 <setting data_type="select" value="StartupSecsBeforeRecording" 294 label="Startup before rec. (secs)" 295 default_data="120" 296 setting_type="global" 297 help_text="The amount of time the master backend will be 298 woken up before a recording starts."> 299 <option display="5" data="5" /> 300 <option display="15" data="15" /> 301 <option display="30" data="30" /> 302 <option display="60" data="60" /> 303 <option display="120" data="120" /> 304 <option display="300" data="300" /> 305 <option display="600" data="600" /> 306 <option display="1200" data="1200" /> 307 </setting> 308 <setting data_type="string" value="WakeupTimeFormat" 309 label="Wakeup time format" 310 default_data="hh:mm yyyy-MM-dd" 311 setting_type="global" 312 help_text="The format of the time string passed to the 313 'setWakeuptime Command' as $time. See 314 QT::QDateTime.toString() for details. Set to 'time_t' for 315 seconds since epoch." /> 316 <setting data_type="string" value="SetWakeuptimeCommand" 317 label="Command to set Wakeup Time" 318 default_data="" 319 setting_type="global" 320 help_text="The command used to set the wakeup time (passed as 321 $time) for the Master Backend" /> 322 <setting data_type="string" value="ServerHaltCommand" 323 label="Server halt command" 324 default_data="sudo /sbin/halt -p" 325 setting_type="global" 326 help_text="The command used to halt the backends." /> 327 <setting data_type="string" value="preSDWUCheckCommand" 328 label="Pre Shutdown check-command" 329 default_data="" 330 setting_type="global" 331 help_text="A command executed before the backend would 332 shutdown. The return value determines if 333 the backend can shutdown. 0 - yes, 334 1 - restart idling, 335 2 - reset the backend to wait for a frontend." /> 336 </group> 337 <group human_label="Backend Wakeup settings" 338 unique_label="backend_wakeup_settings"> 339 340 <group human_label="Master Backends" 341 unique_label="backend_wakeup_settings_master_backends"> 342 <setting data_type="select" value="WOLbackendReconnectWaitTime" 343 label="Delay between wake attempts (secs)" 344 default_data="0" 345 setting_type="global" 346 help_text="Length of time the frontend waits between 347 tries to wake up the master backend. This should be the 348 time your master backend needs to startup."> 349 <option display="Disabled" data="0" /> 350 <option display="1" data="1" /> 351 <option display="2" data="2" /> 352 <option display="4" data="4" /> 353 <option display="8" data="8" /> 354 <option display="15" data="15" /> 355 <option display="30" data="30" /> 356 <option display="60" data="60" /> 357 <option display="120" data="120" /> 358 <option display="300" data="300" /> 359 <option display="600" data="600" /> 360 <option display="1200" data="1200" /> 361 </setting> 362 <setting data_type="select" value="WOLbackendConnectRetry" 363 label="Wake Attempts" 364 setting_type="global" 365 help_text="Number of times the frontend will try to wake 366 up the master backend." 367 default_data="5"> 368 <option display="1" data="1" /> 369 <option display="2" data="2" /> 370 <option display="5" data="5" /> 371 <option display="10" data="10" /> 372 <option display="20" data="20" /> 373 <option display="40" data="40" /> 374 <option display="60" data="60" /> 375 </setting> 376 <setting data_type="string" value="WOLbackendCommand" 377 label="Wake Command" 378 default_data="" 379 setting_type="global" 380 help_text="The command used to wake up your master 381 backend server. For example 382 'sudo /etc/init.d/mythtv-backend restart'." /> 383 </group> 384 385 <group human_label="Slave Backends" 386 unique_label="backend_wakeup_settings_slave_backends"> 387 <setting data_type="string" value="SleepCommand" 388 label="Sleep Command" 389 default_data="" 390 setting_type="host" 391 help_text="The command used to put this slave to sleep. 392 If set, the master backend will use this 393 command to put this slave to sleep when it 394 is not needed for recording." /> 395 <setting data_type="string" value="WakeUpCommand" 396 label="Wake Command" 397 default_data="" 398 setting_type="host" 399 help_text="The command used to wake up this slave from sleep. 400 This setting is not used on the master backend." /> 401 </group> 402 </group> 403 <group human_label="Backend Control" 404 unique_label="backend_control"> 405 <setting data_type="string" value="BackendStopCommand" 406 label="Backend Stop Command" 407 default_data="killall mythbackend" 408 setting_type="global" 409 help_text="The command used to stop the backend 410 when running on the master backend server. 411 For example 'sudo /etc/init.d/mythtv-backend stop'." /> 412 <setting data_type="string" value="BackendStartCommand" 413 label="Backend Start Command" 414 default_data="mythbackend" 415 setting_type="global" 416 help_text="The command used to start the backend 417 when running on the master backend server. 418 For example, 'sudo /etc/init.d/mythtv-backend start'." /> 419 </group> 420 <group human_label="Job Queue (Backend-Specific)" 421 unique_label="job_queue_host"> 422 <setting data_type="select" value="JobQueueMaxSimultaneousJobs" 423 label="Maximum simultaneous jobs on this backend" 424 setting_type="host" 425 help_text="The Job Queue will be limited to running 426 this many simultaneous jobs on this backend." 427 default_data="1"> 428 <option display="0" data="0" /> 429 <option display="1" data="1" /> 430 <option display="2" data="2" /> 431 <option display="3" data="3" /> 432 <option display="4" data="4" /> 433 <option display="5" data="5" /> 434 <option display="6" data="6" /> 435 <option display="7" data="7" /> 436 <option display="8" data="8" /> 437 <option display="9" data="9" /> 438 <option display="10" data="10" /> 439 </setting> 440 <setting data_type="select" value="JobQueueCheckFrequency" 441 label="Job Queue Check frequency (in seconds)" 442 setting_type="host" 443 help_text="When looking for new jobs to process, the 444 Job Queue will wait this long between checks." 445 default_data="60"> 446 <option display="5" data="5" /> 447 <option display="10" data="10" /> 448 <option display="15" data="15" /> 449 <option display="30" data="30" /> 450 <option display="60" data="60" /> 451 <option display="90" data="90" /> 452 <option display="200" data="200" /> 453 <option display="300" data="300" /> 454 </setting> 455 <setting data_type="timeofday" value="JobQueueWindowStart" 456 default_value="00:00" label="Job Queue Start Time" 457 setting_type="host" 458 help_text="This setting controls the start of the Job Queue time 459 window which determines when new jobs will be 460 started." /> 461 <setting data_type="timeofday" value="JobQueueWindowEnd" 462 default_value="23:59" label="Job Queue End Time" 463 setting_type="host" 464 help_text="This setting controls the end of the Job Queue time 465 window which determines when new jobs will be 466 started." /> 467 <setting data_type="select" value="JobQueueCPU" 468 label="CPU Usage" 469 setting_type="host" 470 help_text="This setting controls approximately how 471 much CPU jobs in the queue may consume. 472 On 'High', all available CPU time may be used 473 which could cause problems on slower systems."> 474 <option display="Low" data="0" /> 475 <option display="Medium" data="1" /> 476 <option display="High" data="2" /> 477 </setting> 478 <setting data_type="checkbox" value="JobAllowCommFlag" 479 label="Allow Commercial Detection jobs" 480 default_data="true" 481 setting_type="host" 482 help_text="Allow jobs of this type to run on this backend." /> 483 <setting data_type="checkbox" value="JobAllowTranscode" 484 label="Allow Transcoding jobs" 485 default_data="true" 486 setting_type="host" 487 help_text="Allow jobs of this type to run on this backend." /> 488 <setting data_type="checkbox" value="JobAllowUserJob1" 489 label="Allow User Job #1 on this backend" 490 default_data="0" 491 setting_type="host" 492 help_text="Allow jobs of this type to run on this backend." /> 493 <setting data_type="checkbox" value="JobAllowUserJob2" 494 label="Allow User Job #2 on this backend" 495 default_data="0" 496 setting_type="host" 497 help_text="Allow jobs of this type to run on this backend." /> 498 <setting data_type="checkbox" value="JobAllowUserJob3" 499 label="Allow User Job #3 on this backend" 500 default_data="0" 501 setting_type="host" 502 help_text="Allow jobs of this type to run on this backend." /> 503 <setting data_type="checkbox" value="JobAllowUserJob4" 504 label="Allow User Job #4 on this backend" 505 default_data="0" 506 setting_type="host" 507 help_text="Allow jobs of this type to run on this backend." /> 508 </group> 509 <group human_label="Job Queue (Global)" 510 unique_label="job_queue_global"> 511 <setting data_type="checkbox" value="JobsRunOnRecordHost" 512 label="Run Jobs only on original recording backend" default_data="0" 513 setting_type="global" 514 help_text="If set, jobs in the queue will be required 515 to run on the backend that made the 516 original recording." /> 517 <setting data_type="checkbox" value="AutoCommflagWhileRecording" 518 label="Start Auto-Commercial Flagging jobs when the recording starts" 519 default_data="0" 520 setting_type="global" 521 help_text="If set and Auto Commercial Flagging is ON for 522 a recording, the flagging job will be started 523 as soon as the recording starts. NOT 524 recommended on underpowered systems." /> 525 <setting data_type="string" value="JobQueueCommFlagCommand" 526 label="Commercial Flagger command" 527 default_data="mythcommflag" 528 setting_type="global" 529 help_text="The program used to detect commercials in a 530 recording. The default is 'mythcommflag' 531 if this setting is empty." /> 532 <setting data_type="string" value="JobQueueTranscodeCommand" 533 label="Transcoder command" 534 default_data="mythtranscode" 535 setting_type="global" 536 help_text="The program used to transcode recordings. 537 The default is 'mythtranscode' if this 538 setting is empty." /> 539 <setting data_type="checkbox" value="AutoTranscodeBeforeAutoCommflag" 540 label="Run Transcode Jobs before Auto-Commercial Flagging" 541 default_data="0" 542 setting_type="global" 543 help_text="If set, if both auto-transcode and 544 auto commercial flagging are turned ON for a 545 recording, transcoding will run first, 546 otherwise, commercial flagging runs first." /> 547 <setting data_type="checkbox" value="SaveTranscoding" 548 label="Save original files after transcoding (globally)" 549 default_data="0" 550 setting_type="global" 551 help_text="When set and the transcoder is active, the 552 original files will be renamed to .old once the 553 transcoding is complete." /> 554 </group> 555 <group human_label="Job Queue (Job Commands)" 556 unique_label="job_queue_job_commands"> 557 <setting data_type="string" value="UserJobDesc1" 558 label="User Job #1 Description" 559 default_data="User Job #1" 560 setting_type="global" 561 help_text="The Description for this User Job." /> 562 <setting data_type="string" value="UserJob1" 563 label="User Job #1 Command" 564 default_data="" 565 setting_type="global" 566 help_text="The command to run whenever this User Job 567 number is scheduled." /> 568 <setting data_type="string" value="UserJobDesc2" 569 label="User Job #2 Description" 570 default_data="User Job #2" 571 setting_type="global" 572 help_text="The Description for this User Job." /> 573 <setting data_type="string" value="UserJob2" 574 label="User Job #2 Command" 575 default_data="" 576 setting_type="global" 577 help_text="The command to run whenever this User Job 578 number is scheduled." /> 579 <setting data_type="string" value="UserJobDesc3" 580 label="User Job #3 Description" 581 default_data="User Job #3" 582 setting_type="global" 583 help_text="The Description for this User Job." /> 584 <setting data_type="string" value="UserJob3" 585 label="User Job #3 Command" 586 default_data="" 587 setting_type="global" 588 help_text="The command to run whenever this User Job 589 number is scheduled." /> 590 <setting data_type="string" value="UserJobDesc4" 591 label="User Job #4 Description" 592 default_data="User Job #4" 593 setting_type="global" 594 help_text="The Description for this User Job." /> 595 <setting data_type="string" value="UserJob4" 596 label="User Job #4 Command" 597 default_data="" 598 setting_type="global" 599 help_text="The command to run whenever this User Job 600 number is scheduled." /> 601 </group> 602 <group human_label="UPNP Server Settings" 603 unique_label="upnp_server_settings"> 604 <!-- 605 <setting data_type="checkbox" value="UPnP/RecordingsUnderVideos" 606 label="Include Recordings in Video List" default_data="0" 607 setting_type="global" 608 help_text="If enabled, the master backend will include the 609 list of recorded shows in the list of videos 610 This is mainly to accommodate UPnP players which do not 611 allow more than 1 video section." /> 612 --> 613 <setting data_type="select" value="UPnP/WMPSource" 614 label="Video content to show a WMP Client" 615 default_data="0" 616 setting_type="global" 617 help_text="This forces us to show WMP clients 618 either the Recordings tree or the Video tree 619 when they request a list of videos "> 620 <option display="Recordings" data="0" /> 621 <option display="Videos" data="1" /> 622 </setting> 623 <setting data_type="select" value="UPnP/RebuildDelay" 624 label="UPnP Media Update Time" 625 setting_type="host" 626 help_text="The number of minutes between mythbackend checking 627 for new videos to serve via upnp. 0 = Off. " 628 default_data="30"> 629 <option display="30" data="30" /> 630 <option display="Off" data="0" /> 631 <option display="1" data="1" /> 632 <option display="5" data="5" /> 633 <option display="15" data="15" /> 634 <option display="30" data="30" /> 635 <option display="60" data="60" /> 636 <option display="120" data="120" /> 637 <option display="300" data="300" /> 638 <option display="600" data="600" /> 639 <option display="1440" data="1440" /> 640 </setting> 641 </group> 642 <group human_label="Database Logging" 643 unique_label="database_logging"> 644 <setting data_type="checkbox" value="LogEnabled" 645 label="Log MythTV events to database" 646 default_data="0" 647 setting_type="global" 648 help_text="If enabled, MythTV modules will send event 649 details to the database, where they can be viewed with 650 MythLog or periodically emailed to the administrator." /> 651 <setting data_type="select" value="LogPrintLevel" 652 label="Log Print Threshold" 653 setting_type="host" default_data="-1" 654 help_text="This controls what messages will be printed 655 out as well as being logged to the database."> 656 <option display="All Messages" data="8" /> 657 <option display="Debug and Higher" data="7" /> 658 <option display="Info and Higher" data="6" /> 659 <option display="Notice and Higher" data="5" /> 660 <option display="Warning and Higher" data="4" /> 661 <option display="Error and Higher" data="3" /> 662 <option display="Critical and Higher" data="2" /> 663 <option display="Alert and Higher" data="1" /> 664 <option display="Emergency Only" data="0" /> 665 <option display="Disable Printed Output" data="-1" /> 666 </setting> 667 <setting data_type="checkbox" value="LogCleanEnabled" 668 label="Automatic Log Cleaning Enabled" default_data="0" 669 setting_type="host" 670 help_text="This enables the periodic cleanup of the 671 events stored in the Myth database (see 'Log MythTV 672 events to database')." /> 673 <setting data_type="select" value="LogCleanPeriod" 674 label="Log Cleanup Frequency (Days)" default_data="14" 675 setting_type="host" 676 help_text="The number of days between log cleanup runs."> 677 <option display="Never cleanup" data="0" /> 678 <option display="1" data="1" /> 679 <option display="2" data="2" /> 680 <option display="4" data="4" /> 681 <option display="7" data="7" /> 682 <option display="14" data="14" /> 683 <option display="30" data="30" /> 684 <option display="60" data="60" /> 685 </setting> 686 <setting data_type="select" value="LogCleanDays" 687 label="Number of days to keep acknowledged log entries" 688 default_data="14" 689 setting_type="host" 690 help_text="The number of days before a log entry that has been 691 acknowledged will be deleted by the log cleanup 692 process."> 693 <option display="Never cleanup" data="0" /> 694 <option display="1" data="1" /> 695 <option display="2" data="2" /> 696 <option display="4" data="4" /> 697 <option display="7" data="7" /> 698 <option display="14" data="14" /> 699 <option display="30" data="30" /> 700 <option display="60" data="60" /> 701 </setting> 702 <setting data_type="select" value="LogCleanMax" 703 label="Number of days to keep unacknowledged log entries" 704 default_data="30" 705 setting_type="host" 706 help_text="The number of days before a log entry that 707 has NOT been acknowledged will be deleted by the log 708 cleanup process."> 709 <option display="Never cleanup" data="0" /> 710 <option display="1" data="1" /> 711 <option display="2" data="2" /> 712 <option display="4" data="4" /> 713 <option display="7" data="7" /> 714 <option display="14" data="14" /> 715 <option display="30" data="30" /> 716 <option display="60" data="60" /> 717 </setting> 718 <setting data_type="select" value="LogMaxCount" 719 label="Maximum Number of Entries per Module" 720 default_data="100" 721 setting_type="host" 722 help_text="If there are more than this number of entries for a 723 module, the oldest log entries will be deleted to 724 reduce the count to this number. Set to 0 to disable."> 725 <option display="Disabled" data="0" /> 726 <option display="10" data="10" /> 727 <option display="25" data="25" /> 728 <option display="50" data="50" /> 729 <option display="100" data="100" /> 730 <option display="250" data="250" /> 731 <option display="500" data="500" /> 732 </setting> 733 </group> 734 <group human_label="Program Schedule Downloading Options" 735 unique_label="program_schedule_downloading_options"> 736 <setting data_type="checkbox" value="MythFillEnabled" 737 label="Automatically run mythfilldatabase" 738 default_data="1" 739 setting_type="global" 740 help_text="This enables the automatic execution of 741 mythfilldatabase." /> 742 <setting data_type="string" value="MythFillDatabasePath" 743 setting_type="global" 744 label="mythfilldatabase Program" 745 default_data="mythfilldatabase" 746 help_text="Use 'mythfilldatabase' or the name of a custom 747 script that will populate the program guide info 748 for all your video sources." /> 749 <setting data_type="string" value="MythFillDatabaseArgs" 750 setting_type="global" 751 label="mythfilldatabase Arguments" 752 default_data="" 753 help_text="Any arguments you want passed to the 754 mythfilldatabase program." /> 755 <setting data_type="string" value="MythFillDatabaseLog" 756 setting_type="global" 757 label="mythfilldatabase Log Path" 758 default_data="" 759 help_text="File or directory to use for logging 760 output from the mythfilldatabase program. 761 Leave blank to disable logging." /> 762 <setting data_type="select" value="MythFillPeriod" 763 label="mythfilldatabase Run Frequency (Days)" 764 default_data="1" 765 setting_type="global" 766 help_text="The number of days between mythfilldatabase runs."> 767 <option display="1" data="1" /> 768 <option display="2" data="2" /> 769 <option display="3" data="3" /> 770 <option display="4" data="4" /> 771 <option display="5" data="5" /> 772 <option display="6" data="6" /> 773 <option display="7" data="7" /> 774 <option display="8" data="8" /> 775 <option display="9" data="9" /> 776 <option display="10" data="10" /> 777 <option display="20" data="20" /> 778 <option display="30" data="30" /> 779 </setting> 780 781 <setting data_type="select" value="MythFillMinHour" 782 label="mythfilldatabase Execution Start" 783 default_data="2" 784 setting_type="global" 785 help_text="This setting and the following one define a 786 time period when the mythfilldatabase process is 787 allowed to run."> 788 <option display="12 AM" data="0" /> 789 <option display="1 AM" data="1" /> 790 <option display="2 AM" data="2" /> 791 <option display="3 AM" data="3" /> 792 <option display="4 AM" data="4" /> 793 <option display="5 AM" data="5" /> 794 <option display="6 AM" data="6" /> 795 <option display="7 AM" data="7" /> 796 <option display="8 AM" data="8" /> 797 <option display="9 AM" data="9" /> 798 <option display="10 AM" data="10" /> 799 <option display="11 AM" data="11" /> 800 <option display="12 PM" data="12" /> 801 <option display="1 PM" data="13" /> 802 <option display="2 PM" data="14" /> 803 <option display="3 PM" data="15" /> 804 <option display="4 PM" data="16" /> 805 <option display="5 PM" data="17" /> 806 <option display="6 PM" data="18" /> 807 <option display="7 PM" data="19" /> 808 <option display="8 PM" data="20" /> 809 <option display="9 PM" data="21" /> 810 <option display="10 PM" data="22" /> 811 <option display="11 PM" data="23" /> 812 </setting> 813 814 <setting data_type="select" value="MythFillMaxHour" 815 label="mythfilldatabase Execution End" 816 default_data="5" 817 setting_type="global" 818 help_text="This setting and the preceding one define a 819 time period when the mythfilldatabase process is 820 allowed to run."> 821 <option display="12 AM" data="0" /> 822 <option display="1 AM" data="1" /> 823 <option display="2 AM" data="2" /> 824 <option display="3 AM" data="3" /> 825 <option display="4 AM" data="4" /> 826 <option display="5 AM" data="5" /> 827 <option display="6 AM" data="6" /> 828 <option display="7 AM" data="7" /> 829 <option display="8 AM" data="8" /> 830 <option display="9 AM" data="9" /> 831 <option display="10 AM" data="10" /> 832 <option display="11 AM" data="11" /> 833 <option display="12 PM" data="12" /> 834 <option display="1 PM" data="13" /> 835 <option display="2 PM" data="14" /> 836 <option display="3 PM" data="15" /> 837 <option display="4 PM" data="16" /> 838 <option display="5 PM" data="17" /> 839 <option display="6 PM" data="18" /> 840 <option display="7 PM" data="19" /> 841 <option display="8 PM" data="20" /> 842 <option display="9 PM" data="21" /> 843 <option display="10 PM" data="22" /> 844 <option display="11 PM" data="23" /> 845 </setting> 846 <setting data_type="checkbox" value="MythFillGrabberSuggestsTime" 847 label="Run mythfilldatabase at time suggested by the grabber." 848 default_data="1" 849 setting_type="global" 850 help_text="This setting allows a DataDirect guide data provider 851 to specify the next download time in order to 852 distribute load on their servers. If this setting is 853 enabled, mythfilldatabase Execution Start/End times 854 are ignored." /> 855 </group> 856 </group> 857 </config> -
mythtv/programs/mythbackend/mythsettings.cpp
1 #include <QNetworkInterface> 2 #include <QDomDocument> 3 #include <QFile> 4 5 #include "channelsettings.h" // for ChannelTVFormat::GetFormats() 6 #include "mythsettings.h" 7 #include "frequencies.h" 8 #include "mythcontext.h" 9 #include "mythdb.h" 10 11 static QString indent(uint level) 12 { 13 QString ret; 14 for (uint i = 0; i < level; i++) 15 ret += " "; 16 return ret; 17 } 18 19 static QString extract_query_list( 20 const MythSettingList &settings, MythSetting::SettingType stype) 21 { 22 QString list; 23 24 MythSettingList::const_iterator it = settings.begin(); 25 for (; it != settings.end(); ++it) 26 { 27 const MythSettingGroup *group = 28 dynamic_cast<const MythSettingGroup*>(*it); 29 if (group) 30 { 31 list += extract_query_list(group->settings, stype); 32 continue; 33 } 34 const MythSetting *setting = dynamic_cast<const MythSetting*>(*it); 35 if (setting && (setting->stype == stype)) 36 list += QString(",'%1'").arg(setting->value); 37 } 38 if (!list.isEmpty() && (list[0] == QChar(','))) 39 list = list.mid(1); 40 41 return list; 42 } 43 44 static void fill_setting( 45 MythSettingBase *sb, const QMap<QString,QString> &map, 46 MythSetting::SettingType stype) 47 { 48 const MythSettingGroup *group = 49 dynamic_cast<const MythSettingGroup*>(sb); 50 if (group) 51 { 52 MythSettingList::const_iterator it = group->settings.begin(); 53 for (; it != group->settings.end(); ++it) 54 fill_setting(*it, map, stype); 55 return; 56 } 57 58 MythSetting *setting = dynamic_cast<MythSetting*>(sb); 59 if (setting && (setting->stype == stype)) 60 { 61 QMap<QString,QString>::const_iterator it = map.find(setting->value); 62 if (it != map.end()) 63 setting->data = *it; 64 65 bool do_option_check = false; 66 if (MythSetting::kLocalIPAddress == setting->dtype) 67 { 68 setting->data_list.clear(); 69 setting->display_list.clear(); 70 QList<QHostAddress> list = QNetworkInterface::allAddresses(); 71 for (uint i = 0; i < (uint)list.size(); i++) 72 { 73 if (list[i].toString().contains(":")) 74 continue; // ignore IP6 addresses for now 75 setting->data_list.push_back(list[i].toString()); 76 setting->display_list.push_back(setting->data_list.back()); 77 } 78 if (setting->data_list.isEmpty()) 79 setting->data_list.push_back("127.0.0.1"); 80 do_option_check = true; 81 } 82 else if (MythSetting::kSelect == setting->dtype) 83 { 84 do_option_check = true; 85 } 86 else if (MythSetting::kTVFormat == setting->dtype) 87 { 88 setting->data_list = setting->display_list = 89 ChannelTVFormat::GetFormats(); 90 do_option_check = true; 91 } 92 else if (MythSetting::kFrequencyTable == setting->dtype) 93 { 94 setting->data_list.clear(); 95 for (uint i = 0; chanlists[i].name; i++) 96 setting->data_list.push_back(chanlists[i].name); 97 setting->display_list = setting->data_list; 98 do_option_check = true; 99 } 100 101 if (do_option_check) 102 { 103 if (!setting->data_list.empty() && 104 !setting->data_list.contains(setting->data.toLower(), 105 Qt::CaseInsensitive)) 106 { 107 bool ok; 108 long long idata = setting->data.toLongLong(&ok); 109 if (ok) 110 { 111 uint sel = 0; 112 for (uint i = setting->data_list.size(); i >= 0; i--) 113 { 114 if (idata < setting->data_list[i].toLongLong()) 115 break; 116 sel = i; 117 } 118 setting->data = setting->data_list[sel]; 119 } 120 else 121 { 122 setting->data = 123 (setting->data_list.contains( 124 setting->default_data, Qt::CaseInsensitive)) ? 125 setting->default_data : setting->data_list[0]; 126 } 127 } 128 } 129 } 130 } 131 132 static void fill_settings( 133 MythSettingList &settings, MSqlQuery &query, MythSetting::SettingType stype) 134 { 135 QMap<QString,QString> map; 136 while (query.next()) 137 map[query.value(0).toString()] = query.value(1).toString(); 138 139 MythSettingList::const_iterator it = settings.begin(); 140 for (; it != settings.end(); ++it) 141 fill_setting(*it, map, stype); 142 } 143 144 QString MythSettingGroup::ToHTML(uint depth) const 145 { 146 QString ret; 147 148 ret = indent(depth) + 149 QString("<div class=\"group\" id=\"%1\">\r\n").arg(unique_label); 150 if (!human_label.isEmpty()) 151 { 152 ret += indent(depth+1) + QString("<h%1>%2</h%3>\r\n") 153 .arg(depth+1).arg(human_label).arg(depth+1); 154 } 155 156 MythSettingList::const_iterator it = settings.begin(); 157 for (; it != settings.end(); ++it) 158 ret += (*it)->ToHTML(depth+1); 159 160 ret += indent(depth) +"</div>"; 161 162 return ret; 163 } 164 165 QString MythSetting::ToHTML(uint level) const 166 { 167 QString ret = indent(level) + 168 QString("<div class=\"setting\" id=\"%1_div\">\r\n").arg(value); 169 170 switch (dtype) 171 { 172 case kInteger: 173 case kUnsignedInteger: 174 case kIntegerRange: 175 case kFloat: 176 case kComboBox: 177 case kIPAddress: 178 case kString: 179 case kTimeOfDay: 180 case kOther: 181 ret += indent(level) + 182 "<div class=\"setting_label\">" + label + "</div>\r\n"; 183 ret += indent(level) + 184 QString("<input name=\"%1\" id=\"%2_input\" type=\"text\"" 185 " value=\"%3\"/>\r\n") 186 .arg(value).arg(value).arg(data); 187 ret += indent(level) + 188 QString("<div style=\"display:none;" 189 "position:absolute;left:-4000px\" " 190 "id=\"%1_default\">%2</div>\r\n") 191 .arg(value).arg(default_data); 192 break; 193 case kCheckBox: 194 ret += indent(level) + 195 "<div class=\"setting_label\">" + label + "</div>\r\n"; 196 ret += indent(level) + 197 QString("<input name=\"%1\" id=\"%2_input\" type=\"checkbox\"" 198 " value=\"1\" %3/>\r\n") 199 .arg(value).arg(value).arg((data.toUInt()) ? "checked" : ""); 200 ret += indent(level) + 201 QString("<div style=\"display:none;" 202 "position:absolute;left:-4000px\" " 203 "id=\"%1_default\">%2</div>\r\n") 204 .arg(value).arg(default_data); 205 break; 206 case kLocalIPAddress: 207 case kTVFormat: 208 case kFrequencyTable: 209 case kSelect: 210 ret += indent(level) + 211 "<div class=\"setting_label\">" + label + "</div>\r\n"; 212 ret += indent(level) + 213 QString("<select name=\"%1\" id=\"%2_input\">\r\n") 214 .arg(value).arg(value); 215 for (uint i = 0; (i < (uint)data_list.size()) && 216 (i < (uint)display_list.size()); i++) 217 { 218 ret += indent(level+1) + 219 QString("<option value=\"%1\" %2>%3</option>\r\n") 220 .arg(data_list[i]) 221 .arg((data_list[i].toLower() == data.toLower()) ? 222 "selected" : "") 223 .arg(display_list[i]); 224 } 225 ret += indent(level) + "</select>\r\n"; 226 ret += indent(level) + 227 QString("<div style=\"display:none;" 228 "position:absolute;left:-4000px\" " 229 "id=\"%1_default\">%2</div>\r\n") 230 .arg(value).arg(default_data); 231 break; 232 } 233 234 ret += indent(level) + "</div>\r\n"; 235 236 return ret; 237 } 238 239 MythSetting::SettingType parse_setting_type(const QString &str) 240 { 241 QString s = str.toLower(); 242 if (s=="file") 243 return MythSetting::kFile; 244 if (s=="host") 245 return MythSetting::kHost; 246 if (s=="global") 247 return MythSetting::kGlobal; 248 return MythSetting::kInvalidSettingType; 249 } 250 251 MythSetting::DataType parse_data_type(const QString &str) 252 { 253 QString s = str.toLower(); 254 if (s == "integer") 255 return MythSetting::kInteger; 256 if (s == "unsigned") 257 return MythSetting::kUnsignedInteger; 258 if (s == "integer_range") 259 return MythSetting::kIntegerRange; 260 if (s == "checkbox") 261 return MythSetting::kCheckBox; 262 if (s == "select") 263 return MythSetting::kSelect; 264 if (s == "combobox") 265 return MythSetting::kComboBox; 266 if (s == "tvformat") 267 return MythSetting::kTVFormat; 268 if (s == "frequency_table") 269 return MythSetting::kFrequencyTable; 270 if (s == "float") 271 return MythSetting::kFloat; 272 if (s == "ipaddress") 273 return MythSetting::kIPAddress; 274 if (s == "localipaddress") 275 return MythSetting::kLocalIPAddress; 276 if (s == "string") 277 return MythSetting::kString; 278 if (s == "timeofday") 279 return MythSetting::kTimeOfDay; 280 if (s == "other") 281 return MythSetting::kOther; 282 VERBOSE(VB_IMPORTANT, QString("Unknown type: %1").arg(str)); 283 return MythSetting::kInvalidDataType; 284 } 285 286 bool parse_dom(MythSettingList &settings, const QDomElement &element, 287 const QString &filename) 288 { 289 #define LOC QString("parse_dom(%1@~%2), error: ") \ 290 .arg(filename).arg(e.lineNumber()) 291 292 QDomNode n = element.firstChild(); 293 while (!n.isNull()) 294 { 295 const QDomElement e = n.toElement(); 296 if (e.isNull()) 297 { 298 n = n.nextSibling(); 299 continue; 300 } 301 302 if (e.tagName() == "group") 303 { 304 QString human_label = e.attribute("human_label"); 305 QString unique_label = e.attribute("unique_label"); 306 QString ecma_script = e.attribute("ecma_script"); 307 308 MythSettingGroup *g = new MythSettingGroup( 309 human_label, unique_label, ecma_script); 310 311 if (e.hasChildNodes() && !parse_dom(g->settings, e, filename)) 312 return false; 313 314 settings.push_back(g); 315 } 316 else if (e.tagName() == "setting") 317 { 318 QMap<QString,QString> m; 319 m["value"] = e.attribute("value"); 320 m["setting_type"] = e.attribute("setting_type"); 321 m["label"] = e.attribute("label"); 322 m["help_text"] = e.attribute("help_text"); 323 m["data_type"] = e.attribute("data_type"); 324 325 MythSetting::DataType dtype = parse_data_type(m["data_type"]); 326 if (MythSetting::kInvalidDataType == dtype) 327 { 328 VERBOSE(VB_IMPORTANT, LOC + 329 "Setting has invalid or missing data_type attribute."); 330 return false; 331 } 332 333 QStringList data_list; 334 QStringList display_list; 335 if ((MythSetting::kComboBox == dtype) || 336 (MythSetting::kSelect == dtype)) 337 { 338 if (!e.hasChildNodes()) 339 { 340 VERBOSE(VB_IMPORTANT, LOC + 341 "Setting missing selection items."); 342 return false; 343 } 344 345 QDomNode n2 = e.firstChild(); 346 while (!n2.isNull()) 347 { 348 const QDomElement e2 = n2.toElement(); 349 if (e2.tagName() != "option") 350 { 351 VERBOSE(VB_IMPORTANT, LOC + 352 "Setting selection contains invalid tags."); 353 return false; 354 } 355 QString display = e2.attribute("display"); 356 QString data = e2.attribute("data"); 357 if (data.isEmpty()) 358 { 359 VERBOSE(VB_IMPORTANT, LOC + 360 "Setting selection item missing data."); 361 return false; 362 } 363 display = (display.isEmpty()) ? data : display; 364 data_list.push_back(data); 365 display_list.push_back(display); 366 367 n2 = n2.nextSibling(); 368 } 369 } 370 371 if (MythSetting::kIntegerRange == dtype) 372 { 373 m["range_min"] = e.attribute("range_min"); 374 m["range_max"] = e.attribute("range_max"); 375 } 376 377 QMap<QString,QString>::const_iterator it = m.begin(); 378 for (; it != m.end(); ++it) 379 { 380 if ((*it).isEmpty()) 381 { 382 VERBOSE(VB_IMPORTANT, LOC + 383 QString("Setting has invalid or missing " 384 "%1 attribute") 385 .arg(it.key())); 386 return false; 387 } 388 } 389 390 m["default_data"] = e.attribute("default_data"); 391 392 MythSetting::SettingType stype = 393 parse_setting_type(m["setting_type"]); 394 if (MythSetting::kInvalidSettingType == stype) 395 { 396 VERBOSE(VB_IMPORTANT, LOC + 397 "Setting has invalid setting_type attribute."); 398 return false; 399 } 400 401 long long range_min = m["range_min"].toLongLong(); 402 long long range_max = m["range_max"].toLongLong(); 403 if (range_max < range_min) 404 { 405 VERBOSE(VB_IMPORTANT, LOC + 406 "Setting has invalid range attributes"); 407 return false; 408 } 409 410 MythSetting *s = new MythSetting( 411 m["value"], m["default_data"], stype, 412 m["label"], m["help_text"], dtype, 413 data_list, display_list, range_min, range_max); 414 415 settings.push_back(s); 416 } 417 else 418 { 419 VERBOSE(VB_IMPORTANT, LOC + 420 QString("Unknown element: %1").arg(e.tagName())); 421 return false; 422 } 423 n = n.nextSibling(); 424 } 425 return true; 426 #undef LOC 427 } 428 429 bool parse_settings(MythSettingList &settings, const QString &filename) 430 { 431 QDomDocument doc; 432 QFile f(filename); 433 434 if (!f.open(QIODevice::ReadOnly)) 435 { 436 VERBOSE(VB_IMPORTANT, QString("parse_settings: Can't open: '%1'") 437 .arg(filename)); 438 return false; 439 } 440 441 QString errorMsg; 442 int errorLine = 0; 443 int errorColumn = 0; 444 445 if (!doc.setContent(&f, false, &errorMsg, &errorLine, &errorColumn)) 446 { 447 VERBOSE(VB_IMPORTANT, QString("parse_settings: ") + 448 QString("Parsing: %1 at line: %2 column: %3") 449 .arg(filename).arg(errorLine).arg(errorColumn) + 450 QString("\n\t\t\t%1").arg(errorMsg)); 451 f.close(); 452 return false; 453 } 454 f.close(); 455 456 settings.clear(); 457 return parse_dom(settings, doc.documentElement(), filename); 458 } 459 460 bool load_settings(MythSettingList &settings, const QString &hostname) 461 { 462 MSqlQuery query(MSqlQuery::InitCon()); 463 464 QString list = extract_query_list(settings, MythSetting::kFile); 465 if (!list.isEmpty()) 466 { 467 DatabaseParams params; 468 bool ok = MythDB::LoadDatabaseParamsFromDisk(params, true); 469 if (!ok) 470 return false; 471 472 QMap<QString,QString> map; 473 map["host"] = params.dbHostName; 474 map["port"] = QString::number(params.dbPort); 475 map["ping"] = QString::number(params.dbHostPing); 476 map["database"] = params.dbName; 477 map["user"] = params.dbUserName; 478 map["password"] = params.dbPassword; 479 map["uniqueid"] = params.localHostName; 480 map["wol_enabled"] = 481 QString::number(params.wolEnabled); 482 map["wol_reconnect_count"] = 483 QString::number(params.wolReconnect); 484 map["wol_retry_count "] = 485 QString::number(params.wolRetry); 486 map["wol_command"] = params.wolCommand; 487 488 MythSettingList::const_iterator it = settings.begin(); 489 for (; it != settings.end(); ++it) 490 fill_setting(*it, map, MythSetting::kFile); 491 } 492 493 list = extract_query_list(settings, MythSetting::kHost); 494 QString qstr = 495 "SELECT value, data " 496 "FROM settings " 497 "WHERE hostname = '" + hostname + "' AND " 498 " value in (" + list + ")"; 499 500 if (!list.isEmpty()) 501 { 502 if (!query.exec(qstr)) 503 { 504 MythDB::DBError("HttpConfig::LoadMythSettings() 1", query); 505 return false; 506 } 507 fill_settings(settings, query, MythSetting::kHost); 508 } 509 510 list = extract_query_list(settings, MythSetting::kGlobal); 511 qstr = 512 "SELECT value, data " 513 "FROM settings " 514 "WHERE hostname IS NULL AND " 515 " value in (" + list + ")"; 516 517 if (!list.isEmpty()) 518 { 519 if (!query.exec(qstr)) 520 { 521 MythDB::DBError("HttpConfig::LoadMythSettings() 2", query); 522 return false; 523 } 524 fill_settings(settings, query, MythSetting::kGlobal); 525 } 526 527 return true; 528 } 529 530 bool check_settings(MythSettingList &database_settings, 531 const QMap<QString,QString> ¶ms) 532 { 533 // TODO 534 } -
mythtv/programs/mythbackend/httpconfig.cpp
1 // Qt headers 2 #include <QTextStream> 3 4 // MythTV headers 5 #include "httpconfig.h" 6 #include "backendutil.h" 7 #include "mythxml.h" 8 #include "mythcontext.h" 9 #include "mythdb.h" 10 #include "mythdirs.h" 11 12 HttpConfig::HttpConfig() : HttpServerExtension("HttpConfig", QString()) 13 { 14 } 15 16 HttpConfig::~HttpConfig() 17 { 18 } 19 20 bool HttpConfig::ProcessRequest(HttpWorkerThread*, HTTPRequest *request) 21 { 22 if (!request) 23 return false; 24 25 VERBOSE(VB_IMPORTANT, QString("ProcessRequest '%1' '%2'") 26 .arg(request->m_sBaseUrl).arg(request->m_sMethod)); 27 28 if (request->m_sBaseUrl != "/" && 29 request->m_sBaseUrl.left(7) != "/config") 30 { 31 return false; 32 } 33 34 bool handled = false; 35 if (request->m_sMethod.toLower() == "save") 36 { 37 if (request->m_sBaseUrl.right(7) == "config" && 38 !database_settings.empty()) 39 { 40 PrintHeader(request->m_response, "config"); 41 check_settings(database_settings, request->m_mapParams); 42 load_settings(database_settings, ""); 43 PrintSettings(request->m_response, database_settings); 44 PrintFooter(request->m_response); 45 handled = true; 46 } 47 else 48 { 49 request->m_response << "<html><body><dl>"; 50 QStringMap::const_iterator it = request->m_mapParams.begin(); 51 for (; it!=request->m_mapParams.end(); ++it) 52 { 53 request->m_response << "<dt>"<<it.key()<<"</dt><dd>" 54 <<*it<<"</dd>\r\n"; 55 } 56 request->m_response << "</dl></body></html>"; 57 handled = true; 58 } 59 } 60 61 if ((request->m_sMethod.toLower() == "config") || (NULL == gContext)) 62 { 63 PrintHeader(request->m_response, "config"); 64 QString fn = GetShareDir() + "backend-config/" 65 "config_backend_database.xml"; 66 parse_settings(database_settings, fn); 67 load_settings(database_settings, ""); 68 PrintSettings(request->m_response, database_settings); 69 PrintFooter(request->m_response); 70 handled = true; 71 } 72 else if (request->m_sMethod.toLower() == "general") 73 { 74 PrintHeader(request->m_response, "config/general"); 75 QString fn = GetShareDir() + "backend-config/" 76 "config_backend_general.xml"; 77 parse_settings(general_settings, fn); 78 load_settings(general_settings, gCoreContext->GetHostName()); 79 PrintSettings(request->m_response, general_settings); 80 PrintFooter(request->m_response); 81 handled = true; 82 } 83 84 if (handled) 85 { 86 request->m_eResponseType = ResponseTypeHTML; 87 request->m_mapRespHeaders[ "Cache-Control" ] = 88 "no-cache=\"Ext\", max-age = 0"; 89 } 90 91 return handled; 92 } 93 94 void HttpConfig::PrintHeader(QTextStream &os, const QString &form) 95 { 96 os.setCodec("UTF-8"); 97 98 os << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" " 99 << "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\r\n" 100 << "<html xmlns=\"http://www.w3.org/1999/xhtml\"" 101 << " xml:lang=\"en\" lang=\"en\">\r\n" 102 << "<head>\r\n" 103 << " <meta http-equiv=\"Content-Type\"\r\n" 104 << " content=\"text/html; charset=UTF-8\" />\r\n" 105 << " <style type=\"text/css\" title=\"Default\" media=\"all\">\r\n" 106 << " body {\r\n" 107 << " background-color:#fff;\r\n" 108 << " font:11px verdana, arial, helvetica, sans-serif;\r\n" 109 << " margin:20px;\r\n" 110 << " }\r\n" 111 << " h1 {\r\n" 112 << " font-size:28px;\r\n" 113 << " font-weight:900;\r\n" 114 << " color:#ccc;\r\n" 115 << " letter-spacing:0.5em;\r\n" 116 << " margin-bottom:30px;\r\n" 117 << " width:650px;\r\n" 118 << " text-align:center;\r\n" 119 << " }\r\n" 120 << " h2 {\r\n" 121 << " font-size:18px;\r\n" 122 << " font-weight:800;\r\n" 123 << " color:#360;\r\n" 124 << " border:none;\r\n" 125 << " letter-spacing:0.3em;\r\n" 126 << " padding:0px;\r\n" 127 << " margin-bottom:10px;\r\n" 128 << " margin-top:0px;\r\n" 129 << " }\r\n" 130 << " h3 {\r\n" 131 << " font-size:14px;\r\n" 132 << " font-weight:800;\r\n" 133 << " color:#360;\r\n" 134 << " border:none;\r\n" 135 << " letter-spacing:0.3em;\r\n" 136 << " padding:0px;\r\n" 137 << " margin-bottom:10px;\r\n" 138 << " margin-top:0px;\r\n" 139 << " }\r\n" 140 << " </style>\r\n" 141 << " <title>MythTV Config</title>" 142 << "</head>\r\n" 143 << "<body>\r\n\r\n" 144 << " <h1>MythTV Configuration</h1>\r\n" 145 << " <form action=\"/" << form << "/save\" method=\"POST\">\r\n" 146 << " <div class=\"form_buttons_top\"\r\n" 147 << " id=\"form_buttons_top\">\r\n" 148 << " <input type=\"submit\" value=\"Save Changes\" />\r\n" 149 << " </div>\r\n"; 150 } 151 152 void HttpConfig::PrintFooter(QTextStream &os) 153 { 154 os << " <div class=\"form_buttons_bottom\"\r\n" 155 << " id=\"form_buttons_bottom\">\r\n" 156 << " <input type=\"submit\" value=\"Save Changes\" />\r\n" 157 << " </div>\r\n" 158 << " </form>\r\n" 159 << "</body>\r\n" 160 << "</html>\r\n"; 161 } 162 163 void HttpConfig::PrintSettings(QTextStream &os, const MythSettingList &settings) 164 { 165 MythSettingList::const_iterator it = settings.begin(); 166 for (; it != settings.end(); ++it) 167 os << (*it)->ToHTML(1); 168 } -
mythtv/programs/mythbackend/main_helpers.cpp
312 312 313 313 } 314 314 315 void showUsage(const MythCommandLineParser &cmdlineparser, const QString &version)316 {317 QString help = cmdlineparser.GetHelpString(false);318 QByteArray ahelp = help.toLocal8Bit();319 320 cerr << qPrintable(version) << endl <<321 "Valid options are: " << endl <<322 "-h or --help List valid command line parameters"323 << endl << ahelp.constData() << endl;324 }325 326 315 void setupLogfile(void) 327 316 { 328 317 if (!logfile.isEmpty()) … … 683 672 684 673 bool ismaster = gCoreContext->IsMasterHost(); 685 674 686 g_pUPnp = new MediaServer(ismaster, !cmdline.IsUPnPEnabled());675 g_pUPnp->Init(ismaster, cmdline.IsUPnPEnabled()); 687 676 688 677 if (!ismaster) 689 678 { -
mythtv/programs/mythbackend/mythbackend.pro
22 22 HEADERS += playbacksock.h scheduler.h server.h housekeeper.h backendutil.h 23 23 HEADERS += upnpcdstv.h upnpcdsmusic.h upnpcdsvideo.h mediaserver.h 24 24 HEADERS += mythxml.h upnpmedia.h main_helpers.h backendcontext.h 25 HEADERS += httpconfig.h mythsettings.h 25 26 26 27 SOURCES += autoexpire.cpp encoderlink.cpp filetransfer.cpp httpstatus.cpp 27 28 SOURCES += main.cpp mainserver.cpp playbacksock.cpp scheduler.cpp server.cpp 28 29 SOURCES += housekeeper.cpp backendutil.cpp 29 30 SOURCES += upnpcdstv.cpp upnpcdsmusic.cpp upnpcdsvideo.cpp mediaserver.cpp 30 31 SOURCES += mythxml.cpp upnpmedia.cpp main_helpers.cpp backendcontext.cpp 32 SOURCES += httpconfig.cpp mythsettings.cpp 31 33 32 34 using_oss:DEFINES += USING_OSS 33 35 … … 35 37 36 38 using_valgrind:DEFINES += USING_VALGRIND 37 39 40 xml_conf.path = $${PREFIX}/share/mythtv/backend-config/ 41 xml_conf.files = config_backend_general.xml config_backend_database.xml 42 43 INSTALLS += xml_conf -
mythtv/programs/mythbackend/mediaserver.h
39 39 QString m_sSharePath; 40 40 41 41 public: 42 explicit MediaServer( bool bMaster, bool bDisableUPnp = false ); 42 explicit MediaServer(); 43 void Init(bool bMaster, bool bDisableUPnp = false); 43 44 44 45 virtual ~MediaServer(); 45 46 -
mythtv/programs/mythbackend/mainserver.cpp
521 521 else 522 522 HandleRecorderQuery(listline, tokens, pbs); 523 523 } 524 else if (command == "QUERY_RECORDING_DEVICE") 525 { 526 // TODO 527 } 528 else if (command == "QUERY_RECORDING_DEVICES") 529 { 530 // TODO 531 } 524 532 else if (command == "SET_NEXT_LIVETV_DIR") 525 533 { 526 534 if (tokens.size() != 3) -
mythtv/programs/mythbackend/config_backend_database.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <config> 3 <group human_label="Database Setup" unique_label="database"> 4 <setting setting_type="file" value="host" default_data="localhost" 5 label="Host" data_type="string" 6 help_text="DNS name or IP of server containing database or 7 'localhost' which will connect to the server using 8 a unix pipe." /> 9 <setting setting_type="file" value="port" default_data="3306" label="Port" 10 help_text="Port on which the remote database server listens." 11 data_type="integer_range" range_min="0" range_max="0xffff" /> 12 <setting setting_type="file" value="ping" default_data="1" label="Ping" 13 help_text="Ping the remote server." data_type="checkbox" /> 14 <setting setting_type="file" value="database" default_data="mythconverg" 15 label="Database" data_type="string" 16 help_text="Database containing MythTV tables." /> 17 <setting setting_type="file" value="user" default_data="mythtv" 18 label="User" data_type="string" 19 help_text="Database user name with read and write 20 access to MythTV tables" /> 21 <setting setting_type="file" value="password" default_data="mythtv" 22 label="Password" data_type="string" 23 help_text="Password for database user." /> 24 <group human_label="Database Wake on LAN" default_data="database_wol"> 25 <setting setting_type="file" value="wol_enabled" default_data="1" 26 label="Enabled" data_type="checkbox" 27 help_text="If checked MythTV will attempt to wake the 28 remote database host." /> 29 <setting setting_type="file" value="wol_reconnect_count" default_data="0" 30 label="Reconnect Count" 31 data_type="integer_range" range_min="0" range_max="10" 32 help_text="How often to attempt reconnecting to the database." /> 33 <setting setting_type="file" value="wol_retry_count" default_data="5" 34 label="Retry Count" 35 data_type="integer_range" range_min="0" range_max="10" 36 help_text="How often to attempt to wake the remote 37 database host." /> 38 <setting setting_type="file" value="wol_command" 39 default_data="echo 'WOLsqlServerCommand not set'" 40 label="Command" data_type="string" 41 help_text="Command to execute to wake the 42 remote database host." /> 43 </group> 44 </group> 45 </config>
