diff options
Diffstat (limited to 'abs/core/mythtv/stable-0.25/mythtv/myth_settings.patch')
-rw-r--r-- | abs/core/mythtv/stable-0.25/mythtv/myth_settings.patch | 1981 |
1 files changed, 0 insertions, 1981 deletions
diff --git a/abs/core/mythtv/stable-0.25/mythtv/myth_settings.patch b/abs/core/mythtv/stable-0.25/mythtv/myth_settings.patch deleted file mode 100644 index a96051b..0000000 --- a/abs/core/mythtv/stable-0.25/mythtv/myth_settings.patch +++ /dev/null @@ -1,1981 +0,0 @@ -commit 9b4205fa320c06afde8c6d866b854cb12d3ec99c -Author: root <root@localhost.localdomain> -Date: Fri Sep 28 14:25:06 2012 -0500 - - new patch - - Signed-off-by: root <root@localhost.localdomain> - -diff --git a/mythtv/libs/libmythbase/mythcorecontext.cpp b/mythtv/libs/libmythbase/mythcorecontext.cpp -index 84cb01a..6e3c54a 100644 ---- a/mythtv/libs/libmythbase/mythcorecontext.cpp -+++ b/mythtv/libs/libmythbase/mythcorecontext.cpp -@@ -1260,6 +1260,90 @@ void MythCoreContext::ResetLanguage(void) - d->language.clear(); - } - -+//JM ADDED -+void MythCoreContext::savesettings_togroup (QString src_hostname, -+ QString saved_settingsgroupname ) -+{ -+ return d->m_database->savesettings_togroup(src_hostname, -+ saved_settingsgroupname); -+} -+ -+void MythCoreContext::deletesettings(QString delete_hostname, -+ QString saved_settingsgroupname) -+{ -+ return d->m_database->deletesettings(delete_hostname, -+ saved_settingsgroupname); -+} -+ -+QMap<QString,QStringList> MythCoreContext::list_settingsgroupname() -+{ -+ return d->m_database->list_settingsgroupname(); -+} -+ -+QMap<QString,QStringList> MythCoreContext::diff_settingsgroupname( -+ QString diff_hostname1, -+ QString diff_hostname2, -+ QStringList table_list) -+{ -+ return d->m_database->diff_settingsgroupname(diff_hostname1, -+ diff_hostname2, -+ table_list); -+} -+ -+void MythCoreContext::clonesettings(QString src_hostname, -+ QString saved_settingsgroupname, -+ QStringList table_list, -+ bool is_full_clone, -+ QString dest_hostname) -+{ -+ return d->m_database->clonesettings(src_hostname, -+ saved_settingsgroupname, -+ table_list, -+ is_full_clone, -+ dest_hostname); -+} -+ -+void MythCoreContext::restoresettings(QString dest_hostname, -+ QString saved_settingsgroupname, -+ QStringList table_list ) -+{ -+ return d->m_database->restoresettings( dest_hostname, -+ saved_settingsgroupname, -+ table_list); -+} -+ -+void MythCoreContext::change_hostname(QString old_hostname, -+ QString new_hostname) -+{ -+ return d->m_database->change_hostname(old_hostname, new_hostname) ; -+} -+ -+bool MythCoreContext::settings_check(QString src_hostname, -+ QString saved_settingsgroupname) -+{ -+ return d->m_database->settings_check(src_hostname,saved_settingsgroupname); -+} -+ -+void MythCoreContext::import_settings(QMap<QString,QString> vp_map, -+ QString table) -+{ -+ return d->m_database->import_settings(vp_map, table); -+} -+ -+ -+QMap<QString, QMap<QString,QString> > MythCoreContext::export_settings( -+ QString src_hostname, -+ QString saved_settingsgroupname, -+ QStringList table_list, bool skip_host ) -+{ -+ return d->m_database->export_settings(src_hostname, -+ saved_settingsgroupname, -+ table_list , skip_host ); -+} -+ -+//END JM ADDED -+ -+ - void MythCoreContext::InitLocale(void ) - { - if (!d->m_locale) -diff --git a/mythtv/libs/libmythbase/mythcorecontext.h b/mythtv/libs/libmythbase/mythcorecontext.h -index 0917313..3f6d5f8 100644 ---- a/mythtv/libs/libmythbase/mythcorecontext.h -+++ b/mythtv/libs/libmythbase/mythcorecontext.h -@@ -168,6 +168,40 @@ class MBASE_PUBLIC MythCoreContext : public MythObservable, public MythSocketCBs - QString GetLanguageAndVariant(void); - void ResetLanguage(void); - -+ //JM ADDED -+ void savesettings_togroup(QString src_hostname, -+ QString saved_settingsgroupname ); -+ -+ void deletesettings(QString delete_hostname, -+ QString saved_settingsgroupname); -+ -+ QMap<QString,QStringList> list_settingsgroupname(); -+ QMap<QString,QStringList> diff_settingsgroupname(QString diff_hostname1, -+ QString diff_hostname2, -+ QStringList table_list); -+ -+ void clonesettings(QString src_hostname, -+ QString saved_settingsgroupname, -+ QStringList table_list, -+ bool is_full_clone=TRUE, -+ QString dest_hostname=""); -+ -+ void restoresettings (QString dest_hostname, -+ QString saved_settingsgroupname, -+ QStringList table_list); -+ -+ void change_hostname (QString old_hostname, QString new_hostname); -+ -+ bool settings_check (QString src_hostname ,QString saved_settingsgroupname); -+ void import_settings(QMap<QString,QString> vp_map, QString table); -+ -+ QMap<QString,QMap <QString,QString> > export_settings( -+ QString src_hostname, -+ QString saved_settingsgroupname, -+ QStringList table_list, -+ bool skip_host = FALSE ); -+ //END JM ADDED -+ - private: - MythCoreContextPrivate *d; - -diff --git a/mythtv/libs/libmythbase/mythdb.cpp b/mythtv/libs/libmythbase/mythdb.cpp -index ea30783..e4c1781 100644 ---- a/mythtv/libs/libmythbase/mythdb.cpp -+++ b/mythtv/libs/libmythbase/mythdb.cpp -@@ -774,7 +774,7 @@ void MythDB::OverrideSettingForSession( - QString mk = key.toLower(), mk2 = d->m_localhostname + ' ' + mk, mv = value; - if ("dbschemaver" == mk) - { -- LOG(VB_GENERAL, LOG_ERR, -+ LOG(VB_GENERAL, LOG_ERR, - QString("ERROR: Refusing to allow override for '%1'.").arg(key)); - return; - } -@@ -1055,6 +1055,1015 @@ void MythDB::WriteDelayedSettings(void) - } - } - -+//JM ADDED -+void MythDB::savesettings_togroup(QString src_hostname, -+ QString saved_settingsgroupname ) -+{ -+ LOG(VB_GENERAL, LOG_ERR, QString("Using hostname of : %1") -+ .arg(src_hostname)); -+ LOG(VB_GENERAL, LOG_ERR, QString("Saving to group: %1") -+ .arg(saved_settingsgroupname)); -+ if ( settings_check( src_hostname , "current" ) ) -+ { -+ QStringList table_list; -+ QString hostname_clause; -+ table_list.append("settings"); -+ table_list.append("keybindings"); -+ table_list.append("jumppoints"); -+ if ( src_hostname == "GLOBAL" ) -+ hostname_clause = "hostname IS NULL"; -+ else -+ hostname_clause ="hostname = :HOSTNAME"; -+ -+ foreach (QString table, table_list) -+ { -+ QString dest_tablename = table +"_" + saved_settingsgroupname ; -+ create_new_table(dest_tablename,table); -+ -+ QString query_string; -+ // Remove old saved values -+ MSqlQuery query(MSqlQuery::InitCon()); -+ query_string = QString("DELETE FROM %1 WHERE %2") -+ .arg(dest_tablename) -+ .arg(hostname_clause); -+ -+ //query_string = QString("DELETE FROM %1 WHERE " -+ // "hostname = :HOSTNAME").arg(dest_tablename); -+ -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME" ,src_hostname); -+ query.exec(); -+ -+ //insert all new settings -+ query_string = QString("REPLACE INTO %1 " -+ "SELECT * from %2 where %3") -+ .arg(dest_tablename) -+ .arg(table) -+ .arg(hostname_clause); -+// query_string = QString("REPLACE INTO %1 " -+// "SELECT * from %2 where hostname = :HOSTNAME)") -+// .arg(dest_tablename) -+// .arg(table); -+ -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME",src_hostname); -+ query.exec(); -+ } -+ } -+ else -+ LOG(VB_GENERAL| VB_STDIO|VB_FLUSH, LOG_ERR, -+ QString("Couldn't find settings for: %1 \n").arg(src_hostname)); -+ return; -+ -+}; -+ -+void MythDB::deletesettings(QString delete_hostname, -+ QString saved_settingsgroupname) -+{ -+ LOG(VB_GENERAL, LOG_ERR, QString("Using hostname of : %1") -+ .arg(delete_hostname)); -+ LOG(VB_GENERAL, LOG_ERR, QString("Deleting: %1") -+ .arg(saved_settingsgroupname)); -+ int tempItem; -+ QString src_tablename; -+ QStringList table_list; -+ -+ table_list.append("settings"); -+ table_list.append("keybindings"); -+ table_list.append("jumppoints"); -+ QString hostname_clause; -+ if ( delete_hostname == "GLOBAL" ) -+ hostname_clause = "hostname IS NULL"; -+ else -+ hostname_clause ="hostname = :HOSTNAME"; -+ -+ foreach (QString table, table_list) -+ { -+ src_tablename = find_group_table_name(table, saved_settingsgroupname); -+ MSqlQuery query(MSqlQuery::InitCon()); -+ // Remove old saved values -+ if ( does_table_exist(src_tablename)) -+ { -+ QString query_string = QString("DELETE from %1 " -+ "WHERE %2") -+ .arg(src_tablename) -+ .arg(hostname_clause); -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME" ,delete_hostname); -+ query.exec(); -+ -+ //check if ok to delete table -+ query_string = QString("SELECT count(*) from %1") -+ .arg(src_tablename); -+ query.prepare(query_string); -+ if (query.exec() && query.isActive() && query.size() > 0) -+ { -+ query.next(); -+ tempItem = query.value(0).toInt(); -+ if ( tempItem == 0 ) -+ drop_temp_table(src_tablename); -+ } -+ } -+ else -+ LOG(VB_GENERAL, LOG_ERR, -+ QString("Couldn't find table: %1").arg(src_tablename)); -+ } -+ return; -+}; // end delete settings -+ -+ -+QMap<QString,QStringList> MythDB::list_settingsgroupname() -+{ -+ //Returns a QMAP of "settings_groups: hostname" -+ MSqlQuery query(MSqlQuery::InitCon()); -+ MSqlQuery subquery(MSqlQuery::InitCon()); -+ QString tempItem; -+ QString temp_hostnameItem; -+ QStringList hostname_list; -+ QMap<QString,QStringList> return_list; -+ QString full_table_name; -+ query.prepare( "show tables like \"settings%\" " ); -+ if (query.exec() && query.isActive() && query.size() > 0) -+ { -+ while (query.next()) -+ { -+ full_table_name = query.value(0).toString(); -+ tempItem=query.value(0).toString().remove(QRegExp("settings_")); -+ if ( tempItem != "distro_default" ) -+ { -+ //loop over tables looking for hostnames -+ QString query_string = QString("SELECT DISTINCT " -+ "hostname from %1") -+ .arg(full_table_name); -+ subquery.prepare(query_string); -+ -+ if (subquery.exec() && subquery.isActive() -+ && subquery.size() > 0) -+ { -+ while (subquery.next()) -+ { -+ temp_hostnameItem = subquery.value(0).toString(); -+ hostname_list.append(temp_hostnameItem); -+ } -+ } -+ //Special case of naming for the settings table; -+ //This only affects output. -+ if ( tempItem == "settings" ) -+ return_list["current"] = hostname_list; -+ else -+ return_list[tempItem] = hostname_list; -+ -+ //reset hostname_list for the next group -+ hostname_list = QStringList(); -+ } -+ } -+ } -+ return return_list; -+}; // end list_settingsgroupname -+ -+QMap<QString,QStringList> MythDB::diff_settingsgroupname( -+ QString diff_hostname1 , -+ QString diff_hostname2, -+ QStringList table_list ) -+{ -+ // Returns a QMAP of tablename : diff results -+ LOG(VB_GENERAL, LOG_ERR, QString("Comparing settings for:")); -+ LOG(VB_GENERAL, LOG_ERR, QString("host 1: %1").arg(diff_hostname1)); -+ LOG(VB_GENERAL, LOG_ERR, QString("host 2: %1").arg(diff_hostname2)); -+ -+ QString qstr; -+ QString tempItem; -+ QString tempString; -+ -+ QStringList diff_list; -+ QStringList settings_list; -+ QStringList keybinding_list; -+ -+ QMap<QString,QStringList> return_list; -+ if ( table_list.isEmpty() ) -+ { -+ table_list.append("settings"); -+ table_list.append("keybindings"); -+ } -+ -+ MSqlQuery query(MSqlQuery::InitCon()); -+ foreach (QString table, table_list) -+ { -+ if ( table == "settings") -+ { -+ -+ qstr= "SELECT distinct settings.value, :DIFF_HOSTNAME1 AS `hostname`, settings_a.data, :DIFF_HOSTNAME2 AS `hostname`" -+ " , settings_b.data FROM settings LEFT JOIN settings AS settings_a ON settings_a.value = settings.value AND settings_a.hostname = :DIFF_HOSTNAME1" -+ " LEFT JOIN settings AS settings_b ON settings_b.value = settings.value AND settings_b.hostname = :DIFF_HOSTNAME2" -+ " WHERE settings_a.data != settings_b.data OR " -+ " (settings_a.data IS NULL AND settings_b.data IS NOT NULL) OR (settings_a.data IS NOT NULL AND settings_b.data IS NULL);"; -+ -+ query.prepare(qstr); -+ query.bindValue(":DIFF_HOSTNAME1" , diff_hostname1); -+ query.bindValue(":DIFF_HOSTNAME2" , diff_hostname2); -+ -+ if (query.exec() && query.isActive() && query.size() > 0) -+ { -+ while (query.next()) -+ { -+ tempString=""; -+ //value -+ tempItem = query.value(0).toString(); -+ tempString.append(tempItem); -+ tempString.append("|"); -+ -+ //hostname_1 -+ tempItem = query.value(1).toString(); -+ if (tempItem.isEmpty()) -+ tempItem=diff_hostname1; -+ tempString.append(tempItem); -+ tempString.append("|"); -+ -+ //data -+ tempItem = query.value(2).toString(); -+ if (tempItem.isEmpty()) -+ tempItem="NULL"; -+ tempString.append(tempItem); -+ tempString.append("|"); -+ -+ //hostname_2 -+ tempItem = query.value(3).toString(); -+ if (tempItem.isEmpty()) -+ tempItem=diff_hostname2; -+ tempString.append(tempItem); -+ tempString.append("|"); -+ -+ //data -+ tempItem = query.value(4).toString(); -+ if (tempItem.isEmpty()) -+ tempItem="NULL"; -+ tempString.append(tempItem); -+ -+ settings_list.append(tempString); -+ } -+ return_list["Settings"] = settings_list; -+ } -+ } -+ else if ( table == "keybindings") -+ { -+ -+ qstr="SELECT distinct keybindings.context, keybindings.action, :DIFF_HOSTNAME1 AS `hostname`, keybindings_a.keylist, :DIFF_HOSTNAME2 AS `hostname`, keybindings_b.keylist FROM keybindings " -+ " LEFT JOIN keybindings AS keybindings_a ON keybindings_a.context = keybindings.context AND keybindings_a.action = keybindings.action " -+ " AND keybindings_a.hostname = :DIFF_HOSTNAME1 " -+ " LEFT JOIN keybindings AS keybindings_b ON keybindings_b.context = keybindings.context " -+ " AND keybindings_b.action = keybindings.action AND keybindings_b.hostname = :DIFF_HOSTNAME2 " -+ " WHERE keybindings_a.keylist != keybindings_b.keylist OR " -+ " (keybindings_a.keylist IS NULL AND keybindings_b.keylist IS NOT NULL) OR (keybindings_a.keylist IS NOT NULL AND keybindings_b.keylist IS NULL);"; -+ query.prepare(qstr); -+ query.bindValue(":DIFF_HOSTNAME1" , diff_hostname1); -+ query.bindValue(":DIFF_HOSTNAME2" , diff_hostname2); -+ -+ if (query.exec() && query.isActive() && query.size() > 0) -+ { -+ while (query.next()) -+ { -+ tempString=""; -+ //context -+ tempItem = query.value(0).toString(); -+ tempString.append(tempItem); -+ tempString.append("|"); -+ -+ //action -+ tempItem = query.value(1).toString(); -+ tempString.append(tempItem); -+ tempString.append("|"); -+ -+ //hostname -+ tempItem = query.value(2).toString(); -+ if (tempItem.isEmpty()) -+ tempItem=diff_hostname1; -+ tempString.append(tempItem); -+ tempString.append("|"); -+ -+ //keylist -+ tempItem = query.value(3).toString(); -+ if (tempItem.isEmpty()) -+ tempItem="NULL"; -+ tempString.append(tempItem); -+ tempString.append("|"); -+ -+ //hostname -+ tempItem = query.value(4).toString(); -+ if (tempItem.isEmpty()) -+ tempItem=diff_hostname2; -+ tempString.append(tempItem); -+ tempString.append("|"); -+ -+ //keylist -+ tempItem = query.value(5).toString(); -+ if (tempItem.isEmpty()) -+ tempItem="NULL"; -+ tempString.append(tempItem); -+ keybinding_list.append(tempString); -+ } -+ return_list["Keybindings"] = keybinding_list; -+ } -+ } -+ -+ } -+ return return_list; -+}; //end diff_settingsgroupname -+ -+void MythDB::clonesettings(QString src_hostname, -+ QString saved_settingsgroupname, -+ QStringList table_list, -+ bool is_full_clone, QString dest_hostname) -+{ -+ LOG(VB_GENERAL, LOG_ERR, QString("Using src hostname of : %1") -+ .arg(src_hostname)); -+ LOG(VB_GENERAL, LOG_ERR, QString("Using dest hostname of : %1") -+ .arg(dest_hostname)); -+ LOG(VB_GENERAL, LOG_ERR, QString("Cloning setting group: %1") -+ .arg(saved_settingsgroupname)); -+ LOG(VB_GENERAL, LOG_ERR, QString("Full Copy : %1") -+ .arg(is_full_clone)); -+ -+ MSqlQuery query(MSqlQuery::InitCon()); -+ QStringList::Iterator it; -+ QString current_table; -+ QString dest_tablename; -+ QString temptable; -+ -+ if ( table_list.isEmpty() ) -+ { -+ table_list.append("settings"); -+ table_list.append("keybindings"); -+ table_list.append("jumppoints"); -+ } -+ -+ for ( it = table_list.begin(); it != table_list.end(); ++it ) -+ { -+ current_table = *it ; -+ dest_tablename = find_group_table_name(current_table, -+ saved_settingsgroupname); -+ -+ if ( does_table_exist(dest_tablename)) -+ { -+ // create temp table for merging settings -+ temptable="temp_table_" + dest_tablename; -+ create_temp_table(temptable, current_table ); -+ -+ // copy in stored settings -+ QString query_string = QString("REPLACE INTO %1 " -+ "(SELECT * from %2 where hostname = :HOSTNAME)") -+ .arg(temptable) -+ .arg(dest_tablename); -+ -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME",src_hostname ); -+ query.exec(); -+ -+ // update hostname for dest_hostname -+ query_string = QString("UPDATE %1 set hostname = :HOSTNAME") -+ .arg(temptable); -+ -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME" , dest_hostname ); -+ query.exec(); -+ -+ //if not full clone remove HOST% settings from temp table; -+ if ( current_table == "settings" && !is_full_clone) -+ { -+ query_string = QString("DELETE FROM %1 WHERE " -+ "hostname=:HOSTNAME and value like 'HOST%' " ) -+ .arg(temptable); -+ -+ query.prepare(query_string); -+ query.bindValue( ":HOSTNAME" , dest_hostname ); -+ query.exec(); -+ } -+ -+ //remove current settings from dest table, -+ //if not full clone, then leave HOST% -+ //Need to remove because the old table allows for duplicates -+ -+ if ( current_table == "settings" && !is_full_clone) -+ query_string = QString ("DELETE FROM %1 WHERE " -+ "hostname = :HOSTNAME " -+ "and value not like 'HOST%'") -+ .arg(dest_tablename); -+ -+ else -+ query_string = QString ("DELETE FROM %1 WHERE " -+ "hostname = :HOSTNAME ") -+ .arg(dest_tablename); -+ -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME",dest_hostname); -+ query.exec(); -+ -+ // copy new settings from temp to current -+ query_string = QString("REPLACE INTO %1 " -+ "(SELECT * from %2)") -+ .arg(dest_tablename) -+ .arg(temptable); -+ -+ query.prepare(query_string); -+ query.exec(); -+ -+ // drop temptable -+ drop_temp_table(temptable); -+ } -+ else -+ LOG(VB_GENERAL, LOG_NOTICE, QString("Couldn't find table: %1") -+ .arg(dest_tablename)); -+ } -+}; //end clonesettings -+ -+void MythDB::restoresettings (QString dest_hostname, -+ QString saved_settingsgroupname, -+ QStringList table_list ) -+{ -+ LOG(VB_GENERAL, LOG_NOTICE, QString("Restoring Settings:")); -+ LOG(VB_GENERAL, LOG_NOTICE, QString(" src: %1") -+ .arg(saved_settingsgroupname)); -+ LOG(VB_GENERAL, LOG_NOTICE, QString(" dest:%1") -+ .arg(dest_hostname)); -+ -+ QString hostname_clause; -+ if ( dest_hostname == "GLOBAL" ) -+ hostname_clause = "hostname IS NULL"; -+ else -+ hostname_clause ="hostname = :HOSTNAME"; -+ -+ bool table_check; -+ if ( saved_settingsgroupname == "distro_default" ) -+ table_check = settings_check ( "distro_default" , saved_settingsgroupname ); -+ else -+ table_check = settings_check ( dest_hostname , saved_settingsgroupname ); -+ -+ -+ if ( table_check == TRUE ) -+ { -+ MSqlQuery query(MSqlQuery::InitCon()); -+ QStringList::Iterator it; -+ QString current_table; -+ if ( table_list.isEmpty() ) -+ { -+ table_list.append("settings"); -+ table_list.append("keybindings"); -+ table_list.append("jumppoints"); -+ } -+ -+ for ( it = table_list.begin(); it != table_list.end(); ++it ) -+ { -+ current_table = *it ; -+ //find tablenames to use -+ QString src_tablename = find_group_table_name(current_table, -+ saved_settingsgroupname); -+ -+ QString temptable="temp_table_" + src_tablename; -+ if ( ! does_table_exist(src_tablename)) -+ { -+ LOG(VB_GENERAL, LOG_NOTICE, QString("table does not exist: %1") -+ .arg(src_tablename)); -+ continue; -+ } -+ // create temp table for merging settings -+ create_temp_table(temptable, current_table ); -+ -+ //could copy in current settings here to account for new stuff -+ -+ -+ -+ // copy in stored settings -+ QString query_string; -+ if ( saved_settingsgroupname == "distro_default" ) -+ { //special case for restoring default settings -+ query_string = QString("REPLACE INTO %1 " -+ "(SELECT * from %2 WHERE %3)") -+ .arg(temptable) -+ .arg(src_tablename) -+ .arg(hostname_clause); -+ -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME", "distro_default" ); -+ query.exec(); -+ -+ // update hostname in temp table from distro_default -+ query_string = QString("UPDATE %1 set hostname = :HOSTNAME") -+ .arg(temptable); -+ -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME" , dest_hostname ); -+ query.exec(); -+ -+ } -+ else -+ { //normal use case -+ query_string = QString("REPLACE INTO %1 " -+ "(SELECT * from %2 WHERE %3)") -+ .arg(temptable) -+ .arg(src_tablename) -+ .arg(hostname_clause); -+ -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME",dest_hostname ); -+ query.exec(); -+ } -+ -+ //Remove current settings. -+ //Need to remove because the old table allows for duplicates -+ query_string = QString("DELETE FROM %1 WHERE " -+ "%2") -+ .arg(current_table) -+ .arg(hostname_clause); -+ -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME",dest_hostname); -+ query.exec(); -+ -+ // copy new settings from temp to current -+ query_string = QString("REPLACE INTO %1 " -+ "(SELECT * from %2)") -+ .arg(current_table) -+ .arg(temptable); -+ -+ query.prepare(query_string); -+ query.exec(); -+ // drop temptable -+ drop_temp_table(temptable); -+ } -+ } -+}; //end restore settings -+ -+void MythDB::change_hostname (QString old_hostname, QString new_hostname) -+{ -+ LOG(VB_GENERAL, LOG_NOTICE, QString("Changing hostname from %1 -> %2") -+ .arg(old_hostname) -+ .arg(new_hostname)); -+ -+ MSqlQuery query(MSqlQuery::InitCon()); -+ MSqlQuery sub_query(MSqlQuery::InitCon()); -+ query.prepare( "SHOW TABLES" ); -+ -+ if (query.exec() && query.isActive() && query.size() > 0) -+ { -+ while (query.next()) -+ { -+ QString table_name = query.value(0).toString(); -+ LOG(VB_GENERAL, LOG_NOTICE, QString("Scanning %1") -+ .arg(table_name)); -+ -+ // LOOP OVER TABLES, CHECK IF IT HAS A HOSTNAME FIELD -+ QString query_string=QString("SHOW COLUMNS from %1 " -+ "where field='hostname'") -+ .arg(table_name); -+ sub_query.prepare(query_string); -+ -+ if (sub_query.exec() && sub_query.size() > 0) -+ { //update hostname -+ LOG(VB_GENERAL, LOG_NOTICE, QString(" Updating hostname in: %1") -+ .arg(table_name)); -+ query_string = QString("UPDATE %1 SET hostname = :NEW_HOSTNAME " -+ "WHERE hostname = :OLD_HOSTNAME") -+ .arg(table_name); -+ sub_query.prepare(query_string); -+ sub_query.bindValue(":NEW_HOSTNAME" , new_hostname); -+ sub_query.bindValue(":OLD_HOSTNAME" , old_hostname); -+ sub_query.exec(); -+ } -+ } -+ } -+ -+ -+ -+ -+ -+ -+} -+ -+bool MythDB::settings_check(QString src_hostname, -+ QString saved_settingsgroupname) -+{ -+ int tempItem; -+ bool returncode = FALSE ; -+ QString table="settings"; -+ -+ QString tablename = find_group_table_name(table, saved_settingsgroupname); -+ QString hostname_clause; -+ if ( src_hostname == "GLOBAL" ) -+ hostname_clause = "hostname IS NULL"; -+ else -+ hostname_clause ="hostname = :HOSTNAME"; -+ -+ if (does_table_exist (tablename)) -+ { -+ MSqlQuery query(MSqlQuery::InitCon()); -+ QString query_string = QString("SELECT COUNT(data) from %1 " -+ "WHERE %2") -+ .arg(tablename) -+ .arg(hostname_clause); -+ -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME" , src_hostname ); -+ -+ if (query.exec() && query.isActive() && query.size() > 0 ) -+ { -+ while (query.next()) -+ { -+ tempItem = query.value(0).toInt(); -+ if ( tempItem >= 1 ) -+ returncode = TRUE; -+ else -+ { -+ LOG(VB_GENERAL, LOG_NOTICE, -+ QString("Group %1 does not contain" -+ " valid settings") -+ .arg(saved_settingsgroupname)); -+ } -+ } -+ } -+ } -+ else -+ LOG(VB_GENERAL, LOG_NOTICE, QString("Couldn't find table: %1") -+ .arg(tablename)); -+ return returncode; -+}; // end settings_check -+ -+void MythDB::import_settings(QMap<QString,QString> vp_map, -+ QString table) -+{ -+ MSqlQuery query(MSqlQuery::InitCon()); -+ -+ //IMPORT SETTINGS TABLE -+ if (table.startsWith("settings")) -+ { -+ if ( table != "settings" ) -+ create_new_table(table,"settings"); -+ QString hostname = vp_map.value("hostname"); -+ QString value = vp_map.value("value"); -+ QString data = vp_map.value("data"); -+ -+ QString hostname_clause; -+ QVariant import_hostname = QVariant(QVariant::String); -+ -+ if ( hostname.isEmpty()) -+ hostname_clause = "hostname IS NULL"; -+ else -+ { -+ hostname_clause ="hostname = :HOSTNAME"; -+ import_hostname = hostname; -+ } -+ -+ QString query_string=QString("SELECT value, data, hostname " -+ "FROM %1 " -+ "WHERE %2 AND value = :VALUE " -+ "ORDER BY value") -+ .arg(table) -+ .arg(hostname_clause); -+ -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME", hostname); -+ query.bindValue(":VALUE", value); -+ -+ // if already exisiting records then update, otherwise insert -+ if (query.exec() && query.isActive()) -+ { -+ MSqlQuery sub_query(MSqlQuery::InitCon()); -+ if ( query.size() > 0 ) -+ { -+ query_string = QString("UPDATE " -+ "%1 " -+ "set data = :DATA " -+ "WHERE %2 AND " -+ "value = :VALUE ") -+ .arg(table) -+ .arg(hostname_clause); -+ -+ sub_query.prepare(query_string); -+ sub_query.bindValue(":HOSTNAME", import_hostname); -+ sub_query.bindValue(":VALUE", value); -+ sub_query.bindValue(":DATA", data); -+ sub_query.exec(); -+ } -+ else -+ { -+ query_string = QString("INSERT INTO " -+ " %1 " -+ "(value,data,hostname) " -+ "VALUES ( :VALUE , :DATA , :HOSTNAME)").arg(table); -+ -+ sub_query.prepare(query_string); -+ sub_query.bindValue(":HOSTNAME", import_hostname); -+ sub_query.bindValue(":VALUE", value); -+ sub_query.bindValue(":DATA", data); -+ sub_query.exec(); -+ } -+ } -+ } -+ //KEYBINDINGS TABLE -+ else if (table.startsWith("keybindings")) -+ { -+ if ( table != "keybindings" ) -+ create_new_table(table,"keybindings"); -+ QString hostname = vp_map.value("hostname"); -+ QString context = vp_map.value("context"); -+ QString action = vp_map.value("action"); -+ QString description = vp_map.value("description"); -+ QString keylist = vp_map.value("keylist"); -+ -+ QString query_string=QString("SELECT context,action,hostname " -+ "FROM %1 " -+ "WHERE hostname = :HOSTNAME AND " -+ "context = :CONTEXT " -+ "AND action = :ACTION ").arg(table); -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME", hostname); -+ query.bindValue(":CONTEXT", context); -+ query.bindValue(":ACTION", action); -+ -+ if (query.exec() && query.isActive()) -+ { -+ MSqlQuery sub_query(MSqlQuery::InitCon()); -+ if ( query.size() > 0 ) -+ { -+ query_string = QString("UPDATE " -+ " %1 " -+ "set keylist = :KEYLIST " -+ "WHERE hostname = :HOSTNAME AND " -+ "context = :CONTEXT " -+ "AND action = :ACTION ").arg(table); -+ -+ sub_query.prepare(query_string); -+ sub_query.bindValue(":HOSTNAME", hostname); -+ sub_query.bindValue(":KEYLIST", keylist); -+ sub_query.bindValue(":CONTEXT", context); -+ sub_query.bindValue(":ACTION", action); -+ sub_query.exec(); -+ } -+ else -+ { -+ query_string = QString("INSERT INTO " -+ " %1 " -+ " (context , action , description , keylist , hostname) " -+ " VALUES( " -+ " :CONTEXT ," -+ " :ACTION , " -+ " :DESCRIPTION , " -+ " :KEYLIST , " -+ " :HOSTNAME)").arg(table) ; -+ -+ sub_query.prepare(query_string); -+ sub_query.bindValue(":HOSTNAME", hostname); -+ sub_query.bindValue(":KEYLIST", keylist); -+ sub_query.bindValue(":CONTEXT", context); -+ sub_query.bindValue(":ACTION", action); -+ sub_query.bindValue(":DESCRIPTION", description); -+ sub_query.exec(); -+ } -+ } -+ } -+ //JUMP POINTS -+ else if (table.startsWith("jumppoints")) -+ { -+ if ( table != "jumppoints" ) -+ create_new_table(table,"jumppoints"); -+ QString hostname = vp_map.value("hostname"); -+ QString description = vp_map.value("description"); -+ QString destination = vp_map.value("destination"); -+ QString keylist = vp_map.value("keylist"); -+ -+ QString query_string=QString("SELECT destination, keylist " -+ "FROM %1 " -+ "WHERE hostname = :HOSTNAME AND " -+ "destination = :DESTINATION " -+ "AND keylist = :KEYLIST ").arg(table); -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME", hostname); -+ query.bindValue(":DESTINATION", destination); -+ query.bindValue(":KEYLIST", keylist); -+ -+ if (query.exec() && query.isActive()) -+ { -+ MSqlQuery sub_query(MSqlQuery::InitCon()); -+ if ( query.size() > 0 ) -+ { -+ query_string = QString("UPDATE " -+ " %1 " -+ "set keylist = :KEYLIST " -+ "WHERE hostname = :HOSTNAME AND " -+ "destination = :DESTINATION ").arg(table); -+ -+ sub_query.prepare(query_string); -+ sub_query.bindValue(":HOSTNAME", hostname); -+ sub_query.bindValue(":KEYLIST", keylist); -+ sub_query.bindValue(":DESTINATION", destination); -+ sub_query.exec(); -+ } -+ else -+ { -+ query_string = QString("INSERT INTO " -+ " %1 " -+ " (description , destination, keylist , hostname) " -+ " VALUES( " -+ " :DESCRIPTION ," -+ " :DESTINATION , " -+ " :KEYLIST , " -+ " :HOSTNAME)").arg(table) ; -+ -+ sub_query.prepare(query_string); -+ sub_query.bindValue(":HOSTNAME", hostname); -+ sub_query.bindValue(":KEYLIST", keylist); -+ sub_query.bindValue(":DESTINATION", destination); -+ sub_query.bindValue(":DESCRIPTION", description); -+ sub_query.exec(); -+ } -+ } -+ } -+}; //end import_settings -+ -+QMap<QString, QMap<QString,QString> > -+ MythDB::export_settings(QString src_hostname, -+ QString saved_settingsgroupname, -+ QStringList table_list, bool skip_host ) -+{ -+ QMap<QString, QMap<QString,QString> > result_set; -+ QStringList::Iterator it; -+ QString current_table; -+ int record_count = 0; -+ -+ if ( table_list.isEmpty() ) -+ { -+ table_list.append("settings"); -+ table_list.append("keybindings"); -+ table_list.append("jumppoints"); -+ } -+ -+ MSqlQuery query(MSqlQuery::InitCon()); -+ QString query_string; -+ -+ //loop over tablelist -+ for ( it = table_list.begin(); it != table_list.end(); ++it ) -+ { -+ current_table = *it ; -+ QString sub_sql; -+ QStringList fields; -+ QString field_query; -+ -+ QString table_name = find_group_table_name(current_table, -+ saved_settingsgroupname); -+ -+ QString hostname_clause; -+ if ( src_hostname == "GLOBAL" ) -+ hostname_clause = "hostname IS NULL"; -+ else -+ hostname_clause ="hostname = :HOSTNAME"; -+ -+ // find field names -+ query_string = QString("SHOW COLUMNS from %1").arg(table_name); -+ query.prepare(query_string); -+ -+ //build up field name vars -+ if (query.exec() && query.isActive() && query.size() > 0) -+ { -+ while (query.next()) -+ { -+ if (! field_query.isEmpty()) -+ field_query +=','; -+ QString tempItem = query.value(0).toString(); -+ fields.append(tempItem); -+ field_query += tempItem; -+ } -+ } -+ // when working with settings table skip HOST if skip_host is true -+ if ( current_table == "settings" && skip_host == TRUE ) -+ { -+ QString skip_host_clause; -+ skip_host_clause = " VALUE not like 'HOST%' AND DATA not like 'HardwareProfile%UUID'" ; -+ query_string = QString("SELECT %1 FROM %2 WHERE %3 AND %4") -+ .arg(field_query) -+ .arg(table_name) -+ .arg(hostname_clause) -+ .arg(skip_host_clause); -+ -+ } -+ else -+ { -+ query_string = QString("SELECT %1 FROM %2 WHERE %3") -+ .arg(field_query) -+ .arg(table_name) -+ .arg(hostname_clause); -+ } -+ query.prepare(query_string); -+ query.bindValue(":HOSTNAME" , src_hostname); -+ -+ //looping over each record in the table query -+ if (query.exec() && query.isActive() && query.size() > 0) -+ { -+ while (query.next()) -+ { -+ //construct qmap of elements -+ //add table name -+ QMap<QString,QString> value_pair; -+ value_pair["table"]=table_name; -+ -+ for ( int i=0 ; i < fields.size();i++ ) -+ { -+ QString tempvalue = fields[i]; -+ QString tempItem = query.value(i).toString(); -+ value_pair[tempvalue]=tempItem; -+ } -+ result_set[QString(record_count)] = value_pair; -+ record_count++; -+ } -+ } -+ -+ } // end table loop -+ return result_set; -+}; //end export_settings -+ -+ -+void MythDB::create_new_table (QString create_table_name,QString like_name) -+{ -+ if ( ! does_table_exist(create_table_name)) -+ { -+ MSqlQuery query(MSqlQuery::InitCon()); -+ QString query_string = QString("CREATE TABLE %1 like %2") -+ .arg(create_table_name) -+ .arg(like_name); -+ -+ query.prepare(query_string); -+ query.exec(); -+ } -+ else -+ LOG(VB_GENERAL, LOG_NOTICE, QString("Table is already present," -+ "will not create it: %1") -+ .arg(create_table_name)); -+}; -+ -+ -+void MythDB::drop_temp_table (QString table_name) -+{ -+ MSqlQuery query(MSqlQuery::InitCon()); -+ if (table_name == "settings" | table_name == "keybindings" | table_name == "jumppoints") -+ return; -+ QString query_string = QString("DROP TABLE %1").arg(table_name); -+ query.prepare(query_string); -+ query.exec(); -+ return; -+} -+ -+void MythDB::create_temp_table (QString create_table_name,QString like_name) -+{ -+ MSqlQuery query(MSqlQuery::InitCon()); -+ create_new_table(create_table_name,like_name); -+ QString query_string; -+ if ( like_name == "settings") -+ { -+ query_string = QString ("ALTER TABLE %1 ADD UNIQUE( value)") -+ .arg(create_table_name); -+ query.prepare(query_string); -+ query.exec(); -+ } -+ -+ query_string = QString("TRUNCATE %1").arg(create_table_name); -+ query.prepare(query_string); -+ query.exec(); -+ return; -+} -+ -+bool MythDB::does_table_exist(QString table_name) -+{ -+ bool table_exist = FALSE; -+ QString full_table_name; -+ MSqlQuery query(MSqlQuery::InitCon()); -+ -+ query.prepare( "SHOW TABLES" ); -+ if (query.exec() && query.isActive() && query.size() > 0) -+ { -+ while (query.next()) -+ { -+ full_table_name = query.value(0).toString(); -+ if (table_name == full_table_name) -+ { -+ table_exist = TRUE; -+ break; -+ } -+ } -+ } -+ return table_exist; -+}; -+ -+ -+QString MythDB::find_group_table_name(QString current_table, -+ QString saved_settingsgroupname) -+{ -+ QString table_name; -+ if ( saved_settingsgroupname.toLower() == "current" ) -+ table_name = current_table ; -+ else -+ table_name = current_table + "_" + saved_settingsgroupname ; -+ -+ return table_name; -+}; -+//END JM ADDED -+ - /** - * \brief Set a flag indicating we have successfully connected to the database - */ -diff --git a/mythtv/libs/libmythbase/mythdb.h b/mythtv/libs/libmythbase/mythdb.h -index 79abe56..fd6044e 100644 ---- a/mythtv/libs/libmythbase/mythdb.h -+++ b/mythtv/libs/libmythbase/mythdb.h -@@ -75,6 +75,49 @@ class MBASE_PUBLIC MythDB - - void WriteDelayedSettings(void); - -+ //JM ADDED -+ void savesettings_togroup(QString src_hostname, -+ QString saved_settingsgroupname ); -+ void deletesettings(QString delete_hostname, -+ QString saved_settingsgroupname); -+ -+ QMap<QString,QStringList> list_settingsgroupname(); -+ -+ QMap<QString,QStringList> diff_settingsgroupname(QString diff_hostname1, -+ QString diff_hostname2, -+ QStringList table_list); -+ -+ void clonesettings(QString src_hostname, -+ QString saved_settingsgroupname, -+ QStringList table_list, -+ bool is_full_clone=TRUE, -+ QString dest_hostname=""); -+ -+ void restoresettings (QString dest_hostname, -+ QString saved_settingsgroupname, -+ QStringList table_list); -+ -+ void change_hostname (QString old_hostname, QString new_hostname); -+ bool settings_check (QString src_hostname, QString saved_settingsgroupname); -+ void import_settings(QMap<QString,QString> vp_map, QString table); -+ -+ -+ QMap<QString,QMap <QString,QString> > export_settings( -+ QString src_hostname, -+ QString saved_settingsgroupname, -+ QStringList table_list, -+ bool skip_host = FALSE); -+ -+ void create_new_table (QString create_table_name,QString like_name); -+ void drop_temp_table (QString table_name); -+ void create_temp_table (QString create_table_name,QString like_name); -+ bool does_table_exist(QString table_name); -+ QString find_group_table_name(QString current_table, -+ QString saved_settingsgroupname); -+ //END JM ADDED -+ -+ -+ - void SetHaveDBConnection(bool connected); - void SetHaveSchema(bool schema); - bool HaveSchema(void) const; -diff --git a/mythtv/programs/mythutil/commandlineparser.cpp b/mythtv/programs/mythutil/commandlineparser.cpp -index f4a6035..fdeeb8e 100644 ---- a/mythtv/programs/mythutil/commandlineparser.cpp -+++ b/mythtv/programs/mythutil/commandlineparser.cpp -@@ -118,6 +118,37 @@ void MythUtilCommandLineParser::LoadArguments(void) - << add("--print-template", "printtemplate", false, - "Print the template to be sent to the frontend", "") - ->SetGroup("Messaging") -+ -+ //settingsutil.cpp -+ << add("--save-settings", "savesettings", false, -+ "Save current settings", "") -+ ->SetGroup("Settings") -+ << add("--delete-settings", "deletesettings", false, -+ "Delete current settings", "") -+ ->SetGroup("Settings") -+ << add("--restore-settings", "restoresettings", false, -+ "Restore settings from previous backup", "") -+ ->SetGroup("Settings") -+ << add("--list-groups", "listgroups", false, -+ "List hosts and groups of settings", "") -+ ->SetGroup("Settings") -+ << add("--copy-settings", "copysettings", false, -+ "Copy or Clone settings from one host to another", "") -+ ->SetGroup("Settings") -+ << add("--diff-settings", "diffsettings", false, -+ "Show settings that are different between two hosts", "") -+ ->SetGroup("Settings") -+ << add("--change-hostname", "changehostname", false, -+ "Change the hostname", "") -+ ->SetGroup("Settings") -+ << add("--import-settings", "importsettings", false, -+ "import settings", "") -+ ->SetRequiredChild("infile") -+ -+ << add("--export-settings", "exportsettings", false, -+ "export settings", "") -+ ->SetRequiredChild("outfile") -+ - ); - - // mpegutils.cpp -@@ -140,6 +171,59 @@ void MythUtilCommandLineParser::LoadArguments(void) - add("--bcastaddr", "bcastaddr", "127.0.0.1", "(optional) IP address to send to", "") - ->SetChildOf("message"); - -+ //settingsutils.cpp -+ add("--groupname", "groupname", "", "Group of settings name", "") -+ ->SetRequiredChildOf("savesettings") -+ ->SetRequiredChildOf("restoresettings") -+ ->SetRequiredChildOf("deletesettings") -+ ->SetChildOf("copysettings"); -+ -+ add("--hostname", "hostname", "", "System name to save/restore settings", "") -+ ->SetChildOf("savesettings") -+ ->SetChildOf("restoresettings") -+ ->SetChildOf("copysettings") -+ ->SetChildOf("deletesettings") -+ ->SetChildOf("exportsettings") -+ ->SetChildOf("importsettings"); -+ -+ add("--host_1", "host_1", "", "First host in compare list", "") -+ ->SetRequiredChildOf("diffsettings"); -+ -+ add("--host_2", "host_2", "", "Second host in compare list", "") -+ ->SetRequiredChildOf("diffsettings"); -+ -+ -+ add("--tablelist", "table_list", "", "List of tables to operate on " -+ "[keybindings,settings]", "") -+ ->SetChildOf("diffsettings") -+ ->SetChildOf("restoresettings") -+ ->SetChildOf("copysettings") -+ ->SetChildOf("exportsettings"); -+ -+ add("--clone", "fullclone", false, "Enable copy of all settings, " -+ "including those that are unique to each system.", "") -+ ->SetChildOf("copysettings"); -+ -+ -+ add("--old-host", "oldhost", "", "Hostname to change", "") -+ ->SetRequiredChildOf("changehostname"); -+ -+ add("--new-host", "newhost", "", "New hostname", "") -+ ->SetRequiredChildOf("changehostname") -+ ->SetRequiredChildOf("copysettings"); -+ -+ add("--format", "format", false, "Format output of differences", "") -+ ->SetChildOf("diffsettings"); -+ add("--distro-default", "distro-default", false, "Export settings for" -+ "import into the default table", "") -+ ->SetChildOf("exportsettings"); -+ add("--generic", "generic", false, "export settings without saving " -+ "the hostname", "") -+ ->SetChildOf("exportsettings"); -+ -+ -+ -+ - // Generic Options used by more than one utility - addRecording(); - addInFile(true); -diff --git a/mythtv/programs/mythutil/main.cpp b/mythtv/programs/mythutil/main.cpp -index 418ea01..bd4a1f4 100644 ---- a/mythtv/programs/mythutil/main.cpp -+++ b/mythtv/programs/mythutil/main.cpp -@@ -20,7 +20,7 @@ - #include "jobutils.h" - #include "markuputils.h" - #include "messageutils.h" -- -+#include "settingsutils.h" - - int main(int argc, char *argv[]) - { -@@ -92,6 +92,7 @@ int main(int argc, char *argv[]) - registerJobUtils(utilMap); - registerMarkupUtils(utilMap); - registerMessageUtils(utilMap); -+ registerSettingsUtils(utilMap); - - bool cmdFound = false; - int cmdResult = GENERIC_EXIT_OK; -diff --git a/mythtv/programs/mythutil/mythutil.pro b/mythtv/programs/mythutil/mythutil.pro -index 066e618..87d7952 100644 ---- a/mythtv/programs/mythutil/mythutil.pro -+++ b/mythtv/programs/mythutil/mythutil.pro -@@ -10,7 +10,7 @@ TARGET = mythutil - target.path = $${PREFIX}/bin - INSTALLS = target - --LIBS += $$EXTRA_LIBS -+LIBS += $$EXTRA_LIBS - INCLUDEPATH += ../../libs/libmythbase - - QMAKE_CLEAN += $(TARGET) -@@ -19,8 +19,10 @@ QMAKE_CLEAN += $(TARGET) - HEADERS += mythutil.h commandlineparser.h - HEADERS += backendutils.h fileutils.h jobutils.h markuputils.h - HEADERS += messageutils.h mpegutils.h -+HEADERS += settingsutils.h -+ - SOURCES += main.cpp mythutil.cpp commandlineparser.cpp - SOURCES += backendutils.cpp fileutils.cpp jobutils.cpp markuputils.cpp - SOURCES += messageutils.cpp mpegutils.cpp -- -+SOURCES += settingsutils.cpp - mingw: LIBS += -lwinmm -lws2_32 -diff --git a/mythtv/programs/mythutil/settingsutils.cpp b/mythtv/programs/mythutil/settingsutils.cpp -new file mode 100644 -index 0000000..8fc7b0e ---- /dev/null -+++ b/mythtv/programs/mythutil/settingsutils.cpp -@@ -0,0 +1,586 @@ -+// C++ includes -+#include <iostream> -+ -+//QT includes -+#include <qdom.h> -+#include <QFile> -+#include <QDomElement> -+ -+// libmyth* includes -+#include "compat.h" -+#include "exitcodes.h" -+#include "mythlogging.h" -+#include "mythcontext.h" -+ -+ -+#include "settingsutils.h" -+ -+ -+static int SaveSettings(const MythUtilCommandLineParser &cmdline) -+{ -+ QString src_hostname; -+ QString groupname; -+ -+ if (cmdline.toBool("groupname")) -+ groupname = cmdline.toString("groupname"); -+ -+ if (cmdline.toBool("hostname")) -+ src_hostname = cmdline.toString("hostname"); -+ else -+ src_hostname = gCoreContext->GetHostName(); -+ -+ gCoreContext->savesettings_togroup(src_hostname,groupname); -+ return GENERIC_EXIT_OK; -+} -+ -+static int DeleteSettings(const MythUtilCommandLineParser &cmdline) -+{ -+ -+ QString delete_hostname; -+ QString groupname; -+ -+ if (cmdline.toBool("groupname")) -+ groupname = cmdline.toString("groupname"); -+ -+ if (cmdline.toBool("hostname")) -+ delete_hostname = cmdline.toString("hostname"); -+ else -+ delete_hostname = gCoreContext->GetHostName(); -+ -+ -+ gCoreContext->deletesettings(delete_hostname,groupname); -+ -+ return GENERIC_EXIT_OK; -+} -+ -+ -+static int RestoreSettings(const MythUtilCommandLineParser &cmdline) -+{ -+ QString dest_hostname; -+ QString groupname; -+ QString tablestring; -+ QStringList table_list; -+ -+ if (cmdline.toBool("groupname")) -+ groupname = cmdline.toString("groupname"); -+ -+ -+ if (cmdline.toBool("hostname")) -+ dest_hostname = cmdline.toString("hostname"); -+ else -+ dest_hostname = gCoreContext->GetHostName(); -+ -+ if (cmdline.toBool("table_list")) -+ { -+ tablestring = QString(cmdline.toString("table_list")); -+ table_list = tablestring.split(",", QString::SkipEmptyParts); -+ } -+ -+ gCoreContext->restoresettings(dest_hostname, -+ groupname, -+ table_list); -+ -+ return GENERIC_EXIT_OK; -+} -+ -+ -+static int CopySettings(const MythUtilCommandLineParser &cmdline) -+{ -+ QString src_hostname; -+ QString groupname; -+ QString tablestring; -+ QStringList table_list; -+ bool is_full_clone; -+ QString dest_hostname; -+ -+ if (cmdline.toBool("groupname")) -+ groupname = cmdline.toString("groupname"); -+ else -+ groupname = "Current"; -+ -+ if (cmdline.toBool("hostname")) -+ src_hostname = cmdline.toString("hostname"); -+ else -+ src_hostname = gCoreContext->GetHostName(); -+ -+ if (cmdline.toBool("newhost")) -+ dest_hostname = cmdline.toString("newhost"); -+ -+ if (cmdline.toBool("table_list")) -+ { -+ tablestring = QString(cmdline.toString("table_list")); -+ table_list = tablestring.split(",", QString::SkipEmptyParts); -+ } -+ -+ if (cmdline.toBool("fullclone")) -+ is_full_clone = TRUE; -+ else -+ is_full_clone = FALSE; -+ -+ gCoreContext->clonesettings(src_hostname, -+ groupname, -+ table_list, -+ is_full_clone, -+ dest_hostname); -+ -+ return GENERIC_EXIT_OK; -+} -+ -+void print_out_diff_formated(QMap<QString, QStringList> resultset) -+{ -+ QString settings_header; -+ QString keybindings_header; -+ QString tempString; -+ QString tempItem; -+ QString dashline_settings; -+ QString dashline_key; -+ QStringList tempList; -+ -+ QString host_1; -+ QString host_2; -+ QString data_1; -+ QString data_2; -+ QString value; -+ QString context; -+ QString action; -+ -+ int value_width = 35; -+ int data_width = 40; -+ -+ int context_width = 22; -+ int action_width = 22; -+ int key_width = 35; -+ -+ dashline_key = (tempString.fill('-', 133)); -+ dashline_settings = (tempString.fill('-', 130)); -+ -+ QMap<QString, QStringList>::iterator i; -+ -+ -+ for (i = resultset.begin(); i != resultset.end(); ++i) -+ { -+ cout << endl<<i.key().toLocal8Bit().constData() << ": \t" << endl;; -+ //construct the headers -+ if (i.key() == "Settings") -+ { -+ //settings header -+ tempList = (i.value().at(0)).split("|", QString::SkipEmptyParts); -+ host_1 = tempList.at(1); -+ host_2 = tempList.at(3); -+ tempString="|"; -+ tempItem = "Value"; -+ tempString.append(tempItem.leftJustified(value_width)); -+ tempString.append("|"); -+ tempItem = host_1; //hostname 1 -+ tempString.append(tempItem.leftJustified(data_width)); -+ tempString.append("|"); -+ tempItem = host_2; //hostname 2 -+ tempString.append(tempItem.leftJustified(data_width)); -+ tempString.append("|"); -+ settings_header = tempString; -+ -+ cout << settings_header.toLocal8Bit().constData() << endl;; -+ cout << dashline_settings.toLocal8Bit().constData() << endl; -+ } -+ -+ if (i.key() == "Keybindings") -+ { -+ //keybindings_header -+ tempList = (i.value().at(0)).split("|", QString::SkipEmptyParts); -+ host_1 = tempList.at(2); -+ host_2 = tempList.at(4); -+ tempString="|"; -+ tempItem = "Context"; -+ tempString.append(tempItem.leftJustified(context_width)); -+ tempString.append("|"); -+ tempItem = "Action"; -+ tempString.append(tempItem.leftJustified(action_width)); -+ tempString.append("|"); -+ tempItem = host_1; -+ tempString.append(tempItem.leftJustified(key_width)); -+ tempString.append("|"); -+ tempItem = host_2; -+ tempString.append(tempItem.leftJustified(key_width)); -+ tempString.append("|"); -+ keybindings_header = tempString; -+ -+ cout << keybindings_header.toLocal8Bit().constData() << endl;; -+ cout << dashline_key.toLocal8Bit().constData() << endl; -+ -+ } -+ // format each line -+ for (int y = 0; y < i.value().size(); ++y) -+ { -+ if (i.key() == "Settings") -+ { -+ tempList = (i.value().at(y)).split("|", -+ QString::SkipEmptyParts); -+ data_1 = tempList.at(2); -+ data_2 = tempList.at(4); -+ value = tempList.at(0); -+ tempString="|"; -+ tempItem = value; -+ tempString.append(tempItem.leftJustified(value_width)); -+ tempString.append("|"); -+ tempItem = data_1; -+ tempString.append(tempItem.leftJustified(data_width)); -+ tempString.append("|"); -+ tempItem = data_2; -+ tempString.append(tempItem.leftJustified(data_width)); -+ tempString.append("|"); -+ } -+ if (i.key() == "Keybindings") -+ { -+ tempList = (i.value().at(y)).split("|", -+ QString::SkipEmptyParts); -+ data_1 = tempList.at(3); -+ data_2 = tempList.at(5); -+ context = tempList.at(0); -+ action = tempList.at(1); -+ -+ tempString="|"; -+ tempItem = context; -+ tempString.append(tempItem.leftJustified(context_width)); -+ tempString.append("|"); -+ tempItem = action; -+ tempString.append(tempItem.leftJustified(action_width)); -+ tempString.append("|"); -+ tempItem = data_1; -+ tempString.append(tempItem.leftJustified(key_width)); -+ tempString.append("|"); -+ tempItem = data_2; -+ tempString.append(tempItem.leftJustified(key_width)); -+ tempString.append("|"); -+ } -+ -+ cout << tempString.toLocal8Bit().constData()<<endl; -+ } -+ } -+}; -+ -+static int DiffSettings(const MythUtilCommandLineParser &cmdline) -+{ -+ QMap<QString, QStringList> resultset; -+ QString diff_hostname1; -+ QString diff_hostname2; -+ QStringList table_list; -+ bool format_results = FALSE; -+ QMap<QString, QStringList>::iterator i; -+ -+ if (cmdline.toBool("host_1")) -+ diff_hostname1 = cmdline.toString("host_1"); -+ if (cmdline.toBool("host_2")) -+ diff_hostname2 = cmdline.toString("host_2"); -+ -+ if (cmdline.toBool("table_list")) -+ { -+ QString tablestring = QString(cmdline.toString("table_list")); -+ table_list = tablestring.split(",", QString::SkipEmptyParts); -+ } -+ -+ if (cmdline.toBool("format")) -+ format_results = TRUE; -+ -+ resultset = gCoreContext->diff_settingsgroupname(diff_hostname1, -+ diff_hostname2, -+ table_list); -+ if (resultset.isEmpty()) -+ cout << "No differences found" << endl; -+ else -+ { -+ if (format_results) -+ print_out_diff_formated(resultset); -+ else -+ { -+ for (i = resultset.begin(); i != resultset.end(); ++i) -+ { -+ cout << i.key().toLocal8Bit().constData() << " : \t" << endl;; -+ for (int y = 0; y < i.value().size(); ++y) -+ cout << i.value().at(y).toLocal8Bit().constData()<<endl; -+ cout << endl; -+ } -+ } -+ } -+ return GENERIC_EXIT_OK; -+};// DiffSettings -+ -+static int ListGroups(const MythUtilCommandLineParser &cmdline) -+{ -+ QMap<QString, QStringList> resultset; -+ resultset = gCoreContext->list_settingsgroupname(); -+ QMap<QString, QStringList>::iterator i; -+ cout << endl; -+ for (i = resultset.begin(); i != resultset.end(); ++i) -+ { -+ cout << i.key().toLocal8Bit().constData() << " : \t"; -+ for (int y = 0; y < i.value().size(); ++y) -+ cout << i.value().at(y).toLocal8Bit().constData()<<" " ; -+ cout << endl; -+ } -+ return GENERIC_EXIT_OK; -+}; -+ -+static int ImportSettings(const MythUtilCommandLineParser &cmdline) -+{ -+ -+ if (cmdline.toString("infile").isEmpty()) -+ { -+ LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --infile option\n"); -+ return GENERIC_EXIT_INVALID_CMDLINE; -+ } -+ QString import_hostname; -+ bool change_name = FALSE; -+ if (cmdline.toBool("hostname")) -+ { -+ change_name = TRUE; -+ import_hostname = cmdline.toString("hostname"); -+ } -+ QString import_filename = cmdline.toString("infile"); -+ QFile myFile(import_filename); -+ -+ QDomDocument doc( "exported_xml" ); -+ doc.setContent( &myFile ); -+ -+ QDomElement docElement = doc.documentElement(); -+ QDomElement record_element; -+ -+ if ( docElement.nodeName() != "exported_xml" ) -+ { -+ cout << "not a valid exported xml file" << endl; -+ return 1; -+ } -+ -+ QString out_string = "Importing records, please be patient"; -+ cout << out_string.toLocal8Bit().constData() << endl; -+ //Gives list of records in the file + count -+ QDomNodeList nodeList = docElement.childNodes(); -+ int total_records = nodeList.count(); -+ out_string = QString("\nFound %1 records \n").arg(total_records); -+ cout << out_string.toLocal8Bit().constData() << endl; -+ LOG(VB_STDIO|VB_FLUSH, LOG_ERR, out_string); -+ -+ for(QDomNode n = docElement.firstChild(); !n.isNull(); n = n.nextSibling()) -+ { -+ QString table_name=QString(); -+ QMap<QString,QString> value_pair_map ; -+ -+ //find table name for this record -+ QDomNode tablenode=n.namedItem("table"); -+ record_element = tablenode.toElement(); -+ table_name = record_element.text(); -+ -+ //loop over childern of n and convert to element -+ for(QDomNode subn = n.firstChild(); -+ !subn.isNull(); -+ subn = subn.nextSibling()) -+ { -+ record_element = subn.toElement(); -+ if ( record_element.nodeName() == "table" ) -+ continue; -+ if ( change_name && record_element.nodeName() == "hostname" ) -+ value_pair_map[record_element.nodeName()] = import_hostname; -+ else -+ value_pair_map[record_element.nodeName()] = record_element.text(); -+ } -+ if (import_filename.endsWith("syssettings.xml")) -+ { -+ if ( value_pair_map["value"] == "BackendServerIP") -+ { -+ out_string = "sysettings, ignoring backendserver ip record"; -+ cout << out_string.toLocal8Bit().constData() << endl; -+ } -+ else -+ gCoreContext->import_settings(value_pair_map,table_name); -+ } -+ else -+ //perform insert -+ gCoreContext->import_settings(value_pair_map,table_name); -+ } -+ return GENERIC_EXIT_OK; -+}; //end ImportSettings -+ -+ -+static int ExportSettings(const MythUtilCommandLineParser &cmdline) -+{ -+ QMap<QString, QMap<QString,QString> > records; -+ QString src_hostname; -+ QString groupname; -+ QStringList table_list; -+ QString tablestring; -+ bool distro_default = FALSE; -+ bool generic = FALSE; -+ bool skip_host = FALSE; -+ -+ -+ -+ QDomDocument doc("mythutils_exported_settings"); -+ -+ if (cmdline.toBool("groupname")) -+ groupname = cmdline.toString("groupname"); -+ else -+ groupname = "current"; -+ -+ if (cmdline.toBool("hostname")) -+ src_hostname = cmdline.toString("hostname"); -+ else -+ src_hostname = gCoreContext->GetHostName(); -+ -+ if (cmdline.toBool("distro-default")) -+ { -+ distro_default = TRUE; -+ skip_host = TRUE; -+ } -+ if (cmdline.toBool("generic")) -+ { -+ generic = TRUE; -+ //skip_host = TRUE; -+ } -+ if (cmdline.toBool("table_list")) -+ { -+ tablestring = QString(cmdline.toString("table_list")); -+ table_list = tablestring.split(",", QString::SkipEmptyParts); -+ } -+ else -+ table_list << "settings" <<"keybindings" <<"jumppoints" ; -+ -+ if (cmdline.toString("outfile").isEmpty()) -+ { -+ LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing --outfile option\n"); -+ return GENERIC_EXIT_INVALID_CMDLINE; -+ } -+ -+ QString export_filename = cmdline.toString("outfile"); -+ -+ records = gCoreContext->export_settings(src_hostname,groupname, -+ table_list, skip_host); -+ -+ QDomElement exported_xml = doc.createElement("exported_xml"); -+ doc.appendChild(exported_xml); -+ -+ QMap<QString,int> record_count; -+ QMap<QString,QMap<QString,QString> >::iterator i; -+ for (i = records.begin(); i != records.end(); ++i ) -+ { -+ QDomElement record = doc.createElement("record"); -+ exported_xml.appendChild(record); -+ -+ //loop over all values in the record -+ QMap<QString,QString> value_pair = i.value(); -+ QMap<QString, QString>::iterator y; -+ //because we don't know the name of the key, we loop over it -+ for (y = value_pair.begin(); y != value_pair.end(); ++y) -+ { -+ //add key/pair to xml document -+ QDomElement tag = doc.createElement(y.key()); -+ record.appendChild(tag); -+ QDomText t; -+ if ( distro_default == TRUE ) -+ { // If exporting distro_default then change hostname + table -+ if ( y.key() == "hostname" ) -+ { //check for global values here, empty value means global -+ if ( y.value().isEmpty() ) -+ t = doc.createTextNode(y.value()); -+ else -+ t = doc.createTextNode("distro_default"); -+ } -+ else if ( y.key() == "table") -+ t = doc.createTextNode(y.value()+"_distro_default"); -+ else -+ t = doc.createTextNode(y.value()); -+ } -+ -+ else if ( generic == TRUE ) -+ { // If exporting generic then change hostname -+ if ( y.key() == "hostname" ) -+ { //check for global values here, empty value means global -+ if ( y.value().isEmpty() ) -+ t = doc.createTextNode(y.value()); -+ else -+ t = doc.createTextNode("REPLACE_ME"); -+ } -+ else -+ t = doc.createTextNode(y.value()); -+ } -+ else -+ t = doc.createTextNode(y.value()); -+ -+ tag.appendChild(t); -+ //create record counts -+ if ( y.key() == "table" ) -+ { -+ if ( record_count.contains( y.value()) ) -+ { -+ int record_num = record_count[y.value()]; -+ record_count[y.value()] = ++record_num; -+ } -+ else -+ record_count[y.value()] = 1; -+ } -+ } -+ } -+ QFile file( export_filename ); -+ -+ if( !file.open(QIODevice::WriteOnly) ) -+ return -1; -+ -+ QTextStream ts( &file ); -+ ts << doc.toString(); -+ file.close(); -+ QMap<QString, int >::iterator rc_it; -+ for ( rc_it = record_count.begin(); rc_it != record_count.end(); ++rc_it) -+ { -+ QString table = rc_it.key(); -+ int rc_count = rc_it.value(); -+ QString out_string = QString ("Exported table %1: %2 records") -+ .arg(table) -+ .arg(rc_count); -+ cout << out_string.toLocal8Bit().constData() << endl; -+ } -+ return GENERIC_EXIT_OK; -+}; // end export_settings -+ -+ -+static int ChangeHostname(const MythUtilCommandLineParser &cmdline) -+{ -+ -+ QString old_hostname; -+ QString new_hostname; -+ -+ -+ if (cmdline.toBool("oldhost")) -+ old_hostname = cmdline.toString("oldhost"); -+ -+ if (cmdline.toBool("newhost")) -+ new_hostname = cmdline.toString("newhost"); -+ -+ if (old_hostname.isEmpty()) -+ { -+ LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing or empty --old-host option\n"); -+ return GENERIC_EXIT_INVALID_CMDLINE; -+ } -+ -+ if (new_hostname.isEmpty()) -+ { -+ LOG(VB_STDIO|VB_FLUSH, LOG_ERR, "Missing or empty --new-host option\n"); -+ return GENERIC_EXIT_INVALID_CMDLINE; -+ } -+ -+ gCoreContext->change_hostname(old_hostname, new_hostname); -+ -+ return GENERIC_EXIT_OK; -+}; //end ChangeHostname -+ -+void registerSettingsUtils(UtilMap &utilMap) -+{ -+ utilMap["savesettings"] = &SaveSettings; -+ utilMap["deletesettings"] = &DeleteSettings; -+ utilMap["restoresettings"] = &RestoreSettings; -+ utilMap["copysettings"] = &CopySettings; -+ utilMap["diffsettings"] = &DiffSettings; -+ utilMap["listgroups"] = &ListGroups; -+ utilMap["importsettings"] = &ImportSettings; -+ utilMap["exportsettings"] = &ExportSettings; -+ utilMap["changehostname"] = &ChangeHostname; -+} -+ -+/* vim: set expandtab tabstop=4 shiftwidth=4: */ -\ No newline at end of file -diff --git a/mythtv/programs/mythutil/settingsutils.h b/mythtv/programs/mythutil/settingsutils.h -new file mode 100644 -index 0000000..413496c ---- /dev/null -+++ b/mythtv/programs/mythutil/settingsutils.h -@@ -0,0 +1,3 @@ -+#include "mythutil.h" -+ -+void registerSettingsUtils(UtilMap &utilMap); |