From 294a757e2774990e7a788d6437089e730118b5d1 Mon Sep 17 00:00:00 2001
From: James Meyer <james.meyer@operamail.com>
Date: Sun, 15 Apr 2012 13:13:12 -0500
Subject: mythtv .25:  First checkin, still needs a bit of cleanup. This commit
 introduces the dir git_src  which is used as a common dir to build
 plugins/mythweb/mythtv. To update the mythtv pkg, first run
 git_src/checkout_mythtv.sh  then switch to the mythtv package dir and build
 the package as normal. Same applies to mythplugins. I plan to introduce
 another script that will build it all in one step.

Also this checkin doesn't handle the menu updates.  Those will be corrected at a later date.
---
 .../mythtv/stable-0.25/git_src/checkout_mythtv.sh  |   18 +
 abs/core/mythtv/stable-0.25/git_src/mythtv         |    1 +
 abs/core/mythtv/stable-0.25/mythplugins/PKGBUILD   |  143 ++
 .../stable-0.25/mythplugins/mythburn.py.patch      |  303 ++++
 .../mythplugins/mythplugins-mythzoneminder.install |    3 +
 abs/core/mythtv/stable-0.25/mythtv/PKGBUILD        |  113 ++
 abs/core/mythtv/stable-0.25/mythtv/__changelog     |    1 +
 .../mythtv/stable-0.25/mythtv/git_version.patch    |   13 +
 .../stable-0.25/mythtv/menu-xml/HOST_SETTINGS.xml  |   94 +
 abs/core/mythtv/stable-0.25/mythtv/menu-xml/is.xml |    3 +
 .../stable-0.25/mythtv/menu-xml/library.xml.patch  |   12 +
 .../mythtv/stable-0.25/mythtv/menu-xml/linhes.xml  |   59 +
 .../stable-0.25/mythtv/menu-xml/mainmenu.xml.patch |   37 +
 .../stable-0.25/mythtv/menu-xml/mythbackup.xml     |   20 +
 .../stable-0.25/mythtv/menu-xml/mythrestore.xml    |   20 +
 .../mythtv/menu-xml/optical_menu.xml.patch         |   16 +
 .../mythtv/menu-xml/original/create_patch.sh       |    5 +
 .../mythtv/stable-0.25/mythtv/menu-xml/setup.xml   |  111 ++
 .../stable-0.25/mythtv/menu-xml/siriusmenu.xml     |  419 +++++
 .../mythtv/stable-0.25/mythtv/menu-xml/update.xml  |    9 +
 .../mythtv/stable-0.25/mythtv/menu-xml/update2.xml |   20 +
 .../mythtv/menu-xml/util_menu.xml.patch            |   16 +
 .../mythtv/stable-0.25/mythtv/menu-xml/xmmenu.xml  |  574 +++++++
 abs/core/mythtv/stable-0.25/mythtv/myth.sh         |    4 +
 .../mythtv/stable-0.25/mythtv/myth_settings.patch  | 1816 ++++++++++++++++++++
 abs/core/mythtv/stable-0.25/mythtv/mythbackend     |   38 +
 abs/core/mythtv/stable-0.25/mythtv/mythbackend.lr  |    9 +
 abs/core/mythtv/stable-0.25/mythtv/mythbackend.sh  |  117 ++
 abs/core/mythtv/stable-0.25/mythtv/mythfrontend.lr |    9 +
 abs/core/mythtv/stable-0.25/mythtv/mythtv.install  |   63 +
 abs/core/mythtv/stable-0.25/mythtv/pretty          |    9 +
 .../mythtv/stable-0.25/mythtv/smolt_jump.patch     |   10 +
 abs/core/mythtv/stable-0.25/mythweb/PKGBUILD       |   46 +
 .../mythtv/stable-0.25/mythweb/mythweb.php.patch   |   11 +
 34 files changed, 4142 insertions(+)
 create mode 100644 abs/core/mythtv/stable-0.25/git_src/checkout_mythtv.sh
 create mode 160000 abs/core/mythtv/stable-0.25/git_src/mythtv
 create mode 100644 abs/core/mythtv/stable-0.25/mythplugins/PKGBUILD
 create mode 100644 abs/core/mythtv/stable-0.25/mythplugins/mythburn.py.patch
 create mode 100644 abs/core/mythtv/stable-0.25/mythplugins/mythplugins-mythzoneminder.install
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/PKGBUILD
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/__changelog
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/git_version.patch
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/HOST_SETTINGS.xml
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/is.xml
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/library.xml.patch
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/linhes.xml
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/mainmenu.xml.patch
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/mythbackup.xml
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/mythrestore.xml
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/optical_menu.xml.patch
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/original/create_patch.sh
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/setup.xml
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/siriusmenu.xml
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/update.xml
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/update2.xml
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/util_menu.xml.patch
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/menu-xml/xmmenu.xml
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/myth.sh
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/myth_settings.patch
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/mythbackend
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/mythbackend.lr
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/mythbackend.sh
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/mythfrontend.lr
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/mythtv.install
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/pretty
 create mode 100644 abs/core/mythtv/stable-0.25/mythtv/smolt_jump.patch
 create mode 100644 abs/core/mythtv/stable-0.25/mythweb/PKGBUILD
 create mode 100644 abs/core/mythtv/stable-0.25/mythweb/mythweb.php.patch

diff --git a/abs/core/mythtv/stable-0.25/git_src/checkout_mythtv.sh b/abs/core/mythtv/stable-0.25/git_src/checkout_mythtv.sh
new file mode 100644
index 0000000..7691a29
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/git_src/checkout_mythtv.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+#Quick script used to checkout the MythTV source
+#This source should be used build all mythplugins & main program
+
+_gitroot="https://github.com/MythTV/mythtv.git"
+_gitname="mythtv"
+
+
+if [ -d $_gitname ]
+then
+    cd $_gitname && git pull
+    echo "The local files are updated."
+else
+    git clone -b fixes/0.25 $_gitroot
+fi
+echo "GIT checkout done or server timeout"
+
+
diff --git a/abs/core/mythtv/stable-0.25/git_src/mythtv b/abs/core/mythtv/stable-0.25/git_src/mythtv
new file mode 160000
index 0000000..76df8e6
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/git_src/mythtv
@@ -0,0 +1 @@
+Subproject commit 76df8e6c8f7b84a157607d8c25fd19f39d8dc830
diff --git a/abs/core/mythtv/stable-0.25/mythplugins/PKGBUILD b/abs/core/mythtv/stable-0.25/mythplugins/PKGBUILD
new file mode 100644
index 0000000..5a579b6
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythplugins/PKGBUILD
@@ -0,0 +1,143 @@
+# $Id: PKGBUILD 91281 2010-09-26 06:04:21Z remy $
+# Maintainer: Giovanni Scafora <giovanni@archlinux.org>
+
+pkgbase=mythplugins
+pkgname=('mytharchive'
+         'mythbrowser'
+         'mythgallery'
+         'mythgame'
+         'mythmusic'
+         'mythnetvision'
+         'mythnews'
+         'mythweather'
+         'mythzoneminder')
+pkgver=0.25
+pkgrel=1
+arch=('i686' 'x86_64')
+url="http://www.mythtv.org"
+license=('GPL')
+conflicts=('mythmovies')
+makedepends=("mythtv>=${pkgver}" 'mplayer' 'fftw2' 'dvdauthor' 'libexif'
+             'python-imaging' 'libcdaudio' 'taglib' 'perl-xml-simple' 'dcraw'
+             'libvisual' 'perl-xml-xpath' 'perl-image-size' 'perl-json'
+             'perl-class-inspector' 'perl-datetime-format-iso8601'
+             'flac' 'libvorbis' 'python2' 'python-pycurl' 'python-oauth')
+
+source=(mythburn.py.patch)
+
+
+#_gitroot="https://github.com/MythTV/mythtv.git"
+#_gitname="mythplugins"
+
+build() {
+
+ if [ -e ${srcdir}/mythplugins ]
+    then
+        rm -rf ${srcdir}/mythplugins
+    fi
+
+    cd ${startdir}
+    msg "copy in myth plugins src"
+    cp -rp ../git_src/mythtv/mythplugins $srcdir
+    cd ${srcdir}/${pkgbase}
+
+
+
+  msg "The local files are updated."
+  #find . -name '*.py' -type f | xargs sed -i 's@^#!.*python$@#!/usr/bin/python2@'
+  cd ${srcdir}/${pkgbase}
+  ./configure --prefix=/usr \
+              --enable-all
+
+  qmake mythplugins.pro || return 1
+  make || return 1
+}
+
+package_mytharchive() {
+  pkgdesc="MythTV plugin that lets you create DVDs from or archive your recorded shows"
+  depends=("mythtv>=${pkgver}" 'libxmu' 'pil' 'dvdauthor' 'm2vrequantiser')
+#  replaces=('mytharchive')
+  cd "${srcdir}/${_gitname}/${pkgbase}/mytharchive"
+
+#  patch mythburn/scripts/mythburn.py < $srcdir/mythburn.py.patch || return 1
+  make INSTALL_ROOT="${pkgdir}" install || return 1
+}
+
+package_mythbrowser() {
+  pkgdesc="Mini web browser for MythTV"
+  depends=("mythtv>=${pkgver}")
+#  replaces=('mythbrowser')
+  cd "${srcdir}/${_gitname}/${pkgbase}/mythbrowser"
+  make INSTALL_ROOT="${pkgdir}" install || return 1
+}
+
+package_mythgallery() {
+  pkgdesc="Image gallery plugin for MythTV"
+  depends=("mythtv>=${pkgver}" 'libexif')
+#  replaces=('mythgallery')
+  cd "${srcdir}/${_gitname}/${pkgbase}/mythgallery"
+  make INSTALL_ROOT="${pkgdir}" install || return 1
+}
+
+package_mythgame() {
+  pkgdesc="Game emulator module for MythTV"
+  depends=("mythtv>=${pkgver}" 'zlib')
+#  replaces=('mythgame')
+  cd "${srcdir}/${_gitname}/${pkgbase}/mythgame"
+  make INSTALL_ROOT="${pkgdir}" install || return 1
+}
+
+package_mythmusic() {
+  pkgdesc="Music playing plugin for MythTV"
+  depends=("mythtv>=${pkgver}" 'flac' 'libvorbis' 'libcdaudio' 'cdparanoia' 'taglib' 'libvisual-plugins' 'projectm')
+#  replaces=('mythmusic')
+  cd "${srcdir}/${_gitname}/${pkgbase}/mythmusic"
+  make INSTALL_ROOT="${pkgdir}" install || return 1
+}
+
+package_mythnetvision() {
+  pkgdesc="MythNetvision plugin for MythTV"
+
+
+  depends=("mythtv>=${pkgver}" 'python-pycurl' 'python-oauth'  'python-lxml' )
+#  replaces=('mythnetvision')
+  cd "${srcdir}/${_gitname}/${pkgbase}/mythnetvision"
+  make INSTALL_ROOT="${pkgdir}" install || return 1
+}
+
+package_mythnews() {
+  pkgdesc="News checking plugin for MythTV"
+  depends=("mythtv>=${pkgver}")
+#  replaces=('mythnews')
+  cd "${srcdir}/${_gitname}/${pkgbase}/mythnews"
+  make INSTALL_ROOT="${pkgdir}" install || return 1
+}
+
+package_mythvideo() {
+  pkgdesc="Video playback and browsing plugin for MythTV"
+  depends=("mythtv>=${pkgver}" 'mplayer' 'perl-xml-simple')
+#  replaces=('mythvideo')
+  cd "${srcdir}/${_gitname}/${pkgbase}/mythvideo"
+  make INSTALL_ROOT="${pkgdir}" install || return 1
+}
+
+package_mythweather() {
+  pkgdesc="Weather checking plugin for MythTV"
+  depends=("mythtv>=${pkgver}" 'perl-xml-xpath' 'perl-image-size'
+           'perl-class-inspector' 'perl-datetime-format-iso8601'
+           'perl-date-manip' 'perl-json')
+#  replaces=('mythweather')
+  cd "${srcdir}/${_gitname}/${pkgbase}/mythweather"
+  make INSTALL_ROOT="${pkgdir}" install || return 1
+}
+
+package_mythzoneminder() {
+  pkgdesc="Allows for viewing of CCTV cameras through zoneminder"
+  depends=("mythtv>=${pkgver}" zoneminder)
+#  replaces=('mythzoneminder')
+#  install=mythplugins-mythzoneminder.install
+  cd "${srcdir}/${_gitname}/${pkgbase}/mythzoneminder"
+  make INSTALL_ROOT="${pkgdir}" install || return 1
+}
+
+md5sums=('cc7e6887acda167fcc5336af33f29411')
diff --git a/abs/core/mythtv/stable-0.25/mythplugins/mythburn.py.patch b/abs/core/mythtv/stable-0.25/mythplugins/mythburn.py.patch
new file mode 100644
index 0000000..abac7df
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythplugins/mythburn.py.patch
@@ -0,0 +1,303 @@
+--- mythburn.py.orig	2011-09-16 13:41:43.000000000 -0500
++++ mythburn.py	2011-09-17 10:51:36.000000000 -0500
+@@ -38,7 +38,7 @@
+ #******************************************************************************
+ 
+ # version of script - change after each update
+-VERSION="0.1.20101206-1"
++VERSION="0.1.20110821-1"
+ 
+ # keep all temporary files for debugging purposes
+ # set this to True before a first run through when testing
+@@ -75,6 +75,7 @@
+ from fcntl import ioctl
+ import CDROM
+ from shutil import copy
++from subprocess import Popen, PIPE
+ 
+ # media types (should match the enum in mytharchivewizard.h)
+ DVD_SL = 0
+@@ -606,7 +607,7 @@
+ # of a video file from its stream info file
+ 
+ def getVideoParams(folder):
+-    """Returns the video resolution, fps and aspect ratio for the video file from the streamindo.xml file"""
++    """Returns the video resolution, fps and aspect ratio for the video file from the streaminfo.xml file"""
+ 
+     #open the XML containing information about this file
+     infoDOM = xml.dom.minidom.parse(os.path.join(folder, 'streaminfo.xml'))
+@@ -642,14 +643,14 @@
+ # Gets the aspect ratio of a video file from its stream info file
+ 
+ def getAspectRatioOfVideo(index):
+-    """Returns the aspect ratio of the video file (1.333, 1.778, etc)"""
++    """Returns the aspect ratio of the original video file (1.333, 1.778, etc)"""
+ 
+     #open the XML containing information about this file
+-    infoDOM = xml.dom.minidom.parse(os.path.join(getItemTempPath(index), 'streaminfo.xml'))
++    infoDOM = xml.dom.minidom.parse(os.path.join(getItemTempPath(index), 'streaminfo_orig.xml'))
+ 
+     #error out if its the wrong XML
+     if infoDOM.documentElement.tagName != "file":
+-        fatalError("Stream info file doesn't look right (%s)" % os.path.join(getItemTempPath(index), 'streaminfo.xml'))
++        fatalError("Stream info file doesn't look right (%s)" % os.path.join(getItemTempPath(index), 'streaminfo_orig.xml'))
+     video = infoDOM.getElementsByTagName("file")[0].getElementsByTagName("streams")[0].getElementsByTagName("video")[0]
+     if video.attributes["aspectratio"].value != 'N/A':
+         aspect_ratio = float(video.attributes["aspectratio"].value)
+@@ -1762,6 +1763,37 @@
+ 
+ 
+ #############################################################
++# Finds the path of a video file from the local video path
++# or Storage Group
++
++def getVideoPath(filename):
++     # connect
++    db = getDatabaseConnection()
++    # create a cursor
++    cursor = db.cursor()
++    # execute SQL statement
++    cursor.execute("""SELECT dirname 
++                      FROM storagegroup 
++                      WHERE groupname='Videos'""")
++    # get the resultset as a tuple
++    result = cursor.fetchall()
++    # make result a list and add local video path if exists
++    result = [videopath] + list(result)
++    
++    # iterate through result set
++    for sg in result:
++        if doesFileExist(os.path.join("".join(sg), filename)) == True:
++            filepath = "".join(sg)
++            write("Video Path: %s" % filepath)
++            return (filepath)
++            break
++
++    db.close()
++    del db
++    del cursor
++
++
++#############################################################
+ # Pre-process a single video/recording file
+ 
+ def preProcessFile(file, folder, count):
+@@ -1775,11 +1807,11 @@
+     #3. Extract a single frame from the video to use as a thumbnail and resolution check
+     mediafile=""
+ 
+-    if file.attributes["type"].value == "recording":
++    if file.attributes["type"].value=="recording":
+         mediafile = file.attributes["filename"].value
+-    elif file.attributes["type"].value == "video":
+-        mediafile = os.path.join(videopath, file.attributes["filename"].value)
+-    elif file.attributes["type"].value == "file":
++    elif file.attributes["type"].value=="video":
++        mediafile = os.path.join(getVideoPath(file.attributes["filename"].value), file.attributes["filename"].value)
++    elif file.attributes["type"].value=="file":
+         mediafile = file.attributes["filename"].value
+     else:
+         fatalError("Unknown type of video file it must be 'recording', 'video' or 'file'.")
+@@ -1935,9 +1967,39 @@
+ 
+     if result <> 0:
+         fatalError("Failed while running mytharchivehelper to get stream information from %s" % filename)
++    
++    #open the XML containing information about this file
++    infoDOM = xml.dom.minidom.parse(xmlFilename)
++    
++    #error out if its the wrong XML
++    if infoDOM.documentElement.tagName != "file":
++        fatalError("This info file doesn't look right (%s)." % xmlFilename)
++    
++    file = infoDOM.getElementsByTagName("file")[0]
++    video = infoDOM.getElementsByTagName("file")[0].getElementsByTagName("streams")[0].getElementsByTagName("video")[0]
++    
++    #use ffmpeg to get display aspect ratio (DAR) of video
++    cmd = path_ffmpeg[0] + " -i " + quoteFilename(file.attributes["filename"].value) + " 2>&1"
++    aspect_ratio = Popen(cmd, shell=True, stdout=PIPE).stdout.read()
++    if "DAR" in aspect_ratio:
++        #clean DAR string
++        aspect_ratio = aspect_ratio.split("DAR ")[-1].split(",")[0]
++        aspect_ratio = ''.join([c for c in aspect_ratio if c in '1234567890:']).split(":")
++    else:
++        #calculate aspect from video size
++        aspect_ratio = getVideoSize(xmlFilename)
++
++    #convert to decimal
++    aspect_ratio = float(aspect_ratio[0]) / float(aspect_ratio[1])
++
++    write("Video %s aspect ratio is: %s" % (filename, aspect_ratio))
++
++    #set aspect ratio
++    video.setAttribute("aspectratio",str(aspect_ratio))
++    
++    WriteXMLToFile (infoDOM,xmlFilename)
+ 
+     # print out the streaminfo.xml file to the log
+-    infoDOM = xml.dom.minidom.parse(xmlFilename)
+     write("streaminfo.xml :-\n" + infoDOM.toprettyxml("    ", ""), False)
+ 
+ #############################################################
+@@ -2322,7 +2384,7 @@
+ #############################################################
+ # Re-encodes a file to mpeg2
+ 
+-def encodeVideoToMPEG2(source, destvideofile, video, audio1, audio2, aspectratio, profile):
++def encodeVideoToMPEG2(source, destvideofile, video, folder, audio1, audio2, aspectratio, profile):
+     """Encodes an unknown video source file eg. AVI to MPEG2 video and AC3 audio, use ffmpeg"""
+ 
+     profileNode = findEncodingProfile(profile)
+@@ -2347,6 +2409,18 @@
+             value = quoteFilename(destvideofile)
+         if value == "%aspect":
+             value = aspectratio
++        if value == "720x480" or value == "720x576":
++            #add padding to correct for aspects > than 1.9:1
++            videores, fps, videoAR = getVideoParams(folder)
++            if float(videoAR) >= 1.9:
++                if videomode == "ntsc":
++                    videoheight = 480
++                else:
++                    videoheight = 576
++        
++                croppixels = videoheight - (720 / float(videoAR))
++                write("CropPixels Total: %s" % croppixels)
++                value = "720x%d -vf pad=720:%d:0:%d:black" % (videoheight - croppixels, videoheight, croppixels / 2)
+ 
+         # only re-encode the audio if it is not already in AC3 format
+         if audio1[AUDIO_CODEC] == "AC3":
+@@ -2383,12 +2457,12 @@
+         command += " -newaudio" 
+ 
+     #make sure we get the correct stream(s) that we want
+-    command += " -map 0:%d -map 0:%d " % (video[VIDEO_INDEX], audio1[AUDIO_INDEX])
++    command += " -map 0:%d -map 0:%d" % (video[VIDEO_INDEX], audio1[AUDIO_INDEX])
+     if audio2[AUDIO_ID] != -1:
+         command += "-map 0:%d" % (audio2[AUDIO_INDEX])
+ 
+     if passes == 1:
+-        write(command)
++        write("Running ffmpeg: %s" % command)
+         result = runCommand(command)
+         if result!=0:
+             fatalError("Failed while running ffmpeg to re-encode video.\n"
+@@ -2399,7 +2473,7 @@
+ 
+         pass1 = string.replace(command, "%passno","1")
+         pass1 = string.replace(pass1, "%passlogfile", passLog)
+-        write("Pass 1 - " + pass1)
++        write("Running ffmpeg Pass 1: %s" % pass1)
+         result = runCommand(pass1)
+ 
+         if result!=0:
+@@ -2411,7 +2485,7 @@
+ 
+         pass2 = string.replace(command, "%passno","2")
+         pass2 = string.replace(pass2, "%passlogfile", passLog)
+-        write("Pass 2 - " + pass2)
++        write("Running ffmpeg Pass 2: %s" % pass2)
+         result = runCommand(pass2)
+ 
+         if result!=0:
+@@ -2443,10 +2517,6 @@
+     outaudiosamplerate = 48000
+     outaudiocodec = "ac3"
+     deinterlace = 0
+-    croptop = 0
+-    cropright = 0
+-    cropbottom = 0
+-    cropleft = 0
+     qmin = 5
+     qmax = 31
+     qdiff = 31
+@@ -2470,14 +2540,6 @@
+             outvideores = value
+         if name == "-deinterlace":
+             deinterlace = 1
+-        if name == "-croptop":
+-            croptop = value
+-        if name == "-cropright":
+-            cropright = value
+-        if name == "-cropbottom":
+-            cropbottom = value
+-        if name == "-cropleft":
+-           cropleft = value
+         if name == "-qmin":
+            qmin = value
+         if name == "-qmax":
+@@ -2526,7 +2588,6 @@
+     command += "-aspect %s -r %s " % (aspectratio, fps)
+     if (deinterlace == 1):
+         command += "-deinterlace "
+-    command += "-croptop %s -cropright %s -cropbottom %s -cropleft %s " % (croptop, cropright, cropbottom, cropleft)
+     command += "-s %s -b %s -vcodec mpeg2video " % (outvideores, outvideobitrate)
+     command += "-qmin %s -qmax %s -qdiff %s " % (qmin, qmax, qdiff)
+     command += "-ab %s -ar %s -acodec %s " % (outaudiobitrate, outaudiosamplerate, outaudiocodec)
+@@ -2543,7 +2604,7 @@
+     if (not(doesFileExist(os.path.join(folder, "audout")) and doesFileExist(os.path.join(folder, "vidout")))):
+         fatalError("Waited too long for mythtranscode to create the fifos - giving up!!")
+ 
+-    write("Running ffmpeg")
++    write("Running ffmpeg: %s" % command)
+     result = runCommand(command)
+     if result != 0:
+         os.kill(PID, signal.SIGKILL)
+@@ -4724,7 +4785,7 @@
+     elif file.attributes["type"].value=="recording":
+         mediafile = file.attributes["filename"].value
+     elif file.attributes["type"].value=="video":
+-        mediafile=os.path.join(videopath, file.attributes["filename"].value)
++        mediafile = os.path.join(getVideoPath(file.attributes["filename"].value), file.attributes["filename"].value)
+     elif file.attributes["type"].value=="file":
+         mediafile=file.attributes["filename"].value
+     else:
+@@ -4834,8 +4895,7 @@
+                 starttime = -1
+                 usecutlist = -1
+ 
+-            encodeNuvToMPEG2(chanid, starttime, mediafile, os.path.join(folder, "newfile2.mpg"), folder,
+-                         profile, usecutlist)
++            encodeNuvToMPEG2(chanid, starttime, mediafile, os.path.join(folder, "newfile2.mpg"), folder, profile, usecutlist)
+             mediafile = os.path.join(folder, 'newfile2.mpg')
+         else:
+             #we need to re-encode the file, make sure we get the right video/audio streams
+@@ -4861,8 +4921,7 @@
+                 profile = defaultEncodingProfile
+ 
+             #do the re-encode 
+-            encodeVideoToMPEG2(mediafile, os.path.join(folder, "newfile2.mpg"), video,
+-                            audio1, audio2, aspectratio, profile)
++            encodeVideoToMPEG2(mediafile, os.path.join(folder, "newfile2.mpg"), video, folder, audio1, audio2, aspectratio, profile)
+             mediafile = os.path.join(folder, 'newfile2.mpg')
+ 
+             #remove the old mediafile that was run through mythtranscode
+@@ -4936,7 +4995,7 @@
+     elif file.attributes["type"].value=="recording":
+         mediafile = file.attributes["filename"].value
+     elif file.attributes["type"].value=="video":
+-        mediafile=os.path.join(videopath, file.attributes["filename"].value)
++        mediafile = os.path.join(getVideoPath(file.attributes["filename"].value), file.attributes["filename"].value)
+     elif file.attributes["type"].value=="file":
+         mediafile=file.attributes["filename"].value
+     else:
+@@ -4988,8 +5047,7 @@
+                 starttime = -1
+                 usecutlist = -1
+ 
+-            encodeNuvToMPEG2(chanid, starttime, mediafile, os.path.join(folder, "newfile2.mpg"), folder,
+-                         profile, usecutlist)
++            encodeNuvToMPEG2(chanid, starttime, mediafile, os.path.join(folder, "newfile2.mpg"), folder, profile, usecutlist)
+             mediafile = os.path.join(folder, 'newfile2.mpg')
+         else:
+             #we need to re-encode the file, make sure we get the right video/audio streams
+@@ -5015,8 +5073,7 @@
+                 profile = defaultEncodingProfile
+ 
+             #do the re-encode 
+-            encodeVideoToMPEG2(mediafile, os.path.join(folder, "newfile2.mpg"), video,
+-                            audio1, audio2, aspectratio, profile)
++            encodeVideoToMPEG2(mediafile, os.path.join(folder, "newfile2.mpg"), video, folder, audio1, audio2, aspectratio, profile)
+             mediafile = os.path.join(folder, 'newfile2.mpg')
+ 
+     #remove an intermediate file
diff --git a/abs/core/mythtv/stable-0.25/mythplugins/mythplugins-mythzoneminder.install b/abs/core/mythtv/stable-0.25/mythplugins/mythplugins-mythzoneminder.install
new file mode 100644
index 0000000..142212b
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythplugins/mythplugins-mythzoneminder.install
@@ -0,0 +1,3 @@
+post_install() {
+  echo "If you want to use this plugin, install zoneminder from AUR."
+}
diff --git a/abs/core/mythtv/stable-0.25/mythtv/PKGBUILD b/abs/core/mythtv/stable-0.25/mythtv/PKGBUILD
new file mode 100644
index 0000000..d4e4751
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/PKGBUILD
@@ -0,0 +1,113 @@
+# $Id: PKGBUILD 91139 2010-09-23 10:45:09Z remy $
+# Maintainer: Giovanni Scafora <giovanni@archlinux.org>
+# Contributor: Juergen Hoetzel <juergen@archlinux.org>
+# Contributor: <kleptophobiac@gmail.com>
+# Contributor: dorphell <dorphell@archlinux.org>
+
+pkgname=mythtv
+pkgver=0.25
+pkgrel=1
+pkgdesc="A Homebrew PVR project"
+arch=('i686' 'x86_64')
+url="http://www.mythtv.org/"
+license=('GPL')
+depends=('mysql-clients' 'qt' 'lame' 'lirc-utils' 'ffmpeg-svn' 'libxvmc'
+         'fribidi' 'perl-soap-lite' 'perl-date-manip' 'perl-xml-sax'
+         'perl-math-round' 'perl-net-upnp' 'perl-dbd-mysql' 'perl-time-hires'
+         'libavc1394' 'wget' 'libiec61883' 'mysql-python' 'python-lxml'
+         'mesa' 'libxinerama' 'libxrandr' 'faad2' 'libvdpau' 'libcrystalhd-git'
+         'urlgrabber' 'python-pycurl' 'avahi' 'libcec')
+
+makedepends=('yasm' 'libgl' 'git' 'rsync')
+replaces=()
+groups=('pvr')
+#backup=(/usr/share/mythtv/is.xml)
+#options=(!strip)
+#MAKEFLAGS="-j6"
+install='mythtv.install'
+patchs=('myth_settings.patch' 'git_version.patch')
+optdepends=('xmltv: to download tv listings')
+#replaces=('mythtv-contrib')
+conflicts=('mythvideo')
+source=('mythbackend' 'myth.sh' `echo ${patchs[@]:0}`
+        'mythbackend.lr' 'mythfrontend.lr' 'pretty' )
+
+#_gitroot="https://github.com/MythTV/mythtv.git"
+#_gitname="${pkgname}"
+
+build() {
+    if [ -e ${srcdir}/mythtv ]
+    then
+        rm -rf ${srcdir}/mythtv
+    fi
+
+    cd ${startdir}
+    msg "copy in mythtv src"
+    cp -rp ../git_src/mythtv/mythtv $srcdir
+    cd ${srcdir}/$pkgname
+
+    # apply patches
+
+   echo "--------------------------applying patches----------------------------------------------------"
+   for i in `echo ${patchs[@]:0} `
+   do
+       echo applying $i
+       echo "-----------------------------"
+       patch -Np2  -i ${startdir}/src/$i  || return 1
+   done
+   echo "--------------------------done applying patches-----------------------------------------------"
+
+    #sed -i -e "s/\`(svnversion \$\${SVNTREEDIR} 2>\/dev\/null) || echo Unknown\`/$pkgver/" version.pro
+    #find bindings/python contrib -type f | xargs sed -i 's@^#!.*python$@#!/usr/bin/python2@'
+
+  ARCH=${CARCH/_/-}
+  ./configure --prefix=/usr --cpu=${ARCH} \
+              --disable-audio-jack \
+              --disable-audio-pulse \
+              --disable-altivec \
+              --disable-distcc \
+              --disable-ccache \
+              --enable-vdpau \
+              --enable-crystalhd \
+              --dvb-path=/usr/include \
+              --with-bindings=perl,python --python=python2 || return 1
+
+  make all || return 1
+}
+
+package() {
+  cd "${srcdir}/${pkgname}"
+  # basic install
+  make INSTALL_ROOT="${pkgdir}" install
+  # install contrib files
+  rsync -arp --exclude .svn --delete-excluded contrib ${pkgdir}/usr/share/mythtv/ || return 1
+  # install database structure
+  rsync -arp --exclude .svn --delete-excluded database ${pkgdir}/usr/share/mythtv/ || return 1
+  # install docs
+  rsync -arp --exclude .svn --delete-excluded docs ${pkgdir}/usr/share/mythtv/ || return 1
+
+  # patch the xml LinHES style
+  cp -r ${startdir}/menu-xml/*.xml ${pkgdir}/usr/share/mythtv/themes/defaultmenu/
+  mv ${pkgdir}/usr/share/mythtv/themes/defaultmenu/is.xml ${pkgdir}/usr/share/mythtv/
+  cd ${pkgdir}/usr/share/mythtv
+#  patch -p0 < ${startdir}/menu-xml/mainmenu.xml.patch || return 1
+#  patch -p0 < ${startdir}/menu-xml/optical_menu.xml.patch || return 1
+#  patch -p0 < ${startdir}/menu-xml/library.xml.patch || return 1
+  patch -p0 < ${startdir}/menu-xml/util_menu.xml.patch || return 1
+
+  # make log dir
+  mkdir -p ${pkgdir}/var/log/mythtv
+  chown 1000.1000 ${pkgdir}/var/log/mythtv
+  mkdir -p ${pkgdir}/etc/logrotate.d
+  cp ${srcdir}/*.lr ${pkgdir}/etc/logrotate.d
+  mkdir -p ${pkgdir}/etc/cron.hourly/
+  install -m0755 ${srcdir}/pretty ${pkgdir}/etc/cron.hourly/
+}
+
+md5sums=('7ef6de58240e7aad389a0b13d91b1cf6'
+         '2babd4b8e146a7538d18dcd55695b0be'
+         '58ab374d2c51b577359ae77385ab3edf'
+         '03850677ea69ad83ccb92b4c0819224b'
+         'f735805a80b0d1180dee01f9df1b7004'
+         'f407d6af23e74a49540755420f84fa58'
+         '5469d9921b726db750b991c87d226158')
diff --git a/abs/core/mythtv/stable-0.25/mythtv/__changelog b/abs/core/mythtv/stable-0.25/mythtv/__changelog
new file mode 100644
index 0000000..940f84b
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/__changelog
@@ -0,0 +1 @@
+update to 0.24-fixes
diff --git a/abs/core/mythtv/stable-0.25/mythtv/git_version.patch b/abs/core/mythtv/stable-0.25/mythtv/git_version.patch
new file mode 100644
index 0000000..8b1def8
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/git_version.patch
@@ -0,0 +1,13 @@
+diff --git a/mythtv/version.sh b/mythtv/version.sh
+index d2c53af..2cf971f 100755
+--- a/mythtv/version.sh
++++ b/mythtv/version.sh
+@@ -22,7 +22,7 @@ GITREPOPATH="exported"
+ 
+ cd ${GITTREEDIR}
+ 
+-SOURCE_VERSION=$(git describe --dirty || git describe || echo Unknown)
++SOURCE_VERSION=$(git describe | cut -d- -f 3 || echo Unknown)
+ 
+ case "${SOURCE_VERSION}" in
+     exported|Unknown)
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/HOST_SETTINGS.xml b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/HOST_SETTINGS.xml
new file mode 100644
index 0000000..ac52497
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/HOST_SETTINGS.xml
@@ -0,0 +1,94 @@
+<mythmenu name="HOST_SETTINGS">
+
+   <button>
+      <type>MV_NETWORK_SETUP_MENU</type>
+      <text>Network Settings</text>
+      <action>EXEC  mythinstall -s network </action>
+   </button>
+
+   <button>
+      <type>MV_NETWORK_SETUP_MENU</type>
+      <text>DDNS Settings</text>
+      <action>EXEC  mythinstall -s ddns </action>
+   </button>
+   <button>
+      <type>MV_SYSTEM_SETUP_MENU</type>
+      <text>System Type</text>
+      <action>EXEC  mythinstall -s hostype </action>
+   </button>
+
+   <button>
+      <type>MV_SCREENSAVER_SETUP_MENU</type>
+      <text>Screensaver Settings</text>
+      <action>EXEC  mythinstall -s screensaver </action>
+   </button>
+
+   <button>
+      <type>MV_IR_SETUP_MENU</type>
+      <text>Remotes</text>
+       <action>EXEC  mythinstall -s ir </action>
+   </button>
+
+   <button>
+      <type>MV_MISC_SETUP_MENU</type>
+      <text>Miscellanous Settings</text>
+      <action>EXEC  mythinstall -s misc </action>
+   </button>
+
+   <button>
+      <type>MV_SOFTWARE_MENU</type>
+      <text>Software</text>
+      <action>EXEC  mythinstall -s  plugins </action>
+   </button>
+
+   <button>
+      <type>MV_SHUTDOWN_SETUP_MENU</type>
+      <text>Shutdown Settings</text>
+      <action>EXEC  mythinstall -s sleep </action>
+   </button>
+
+   <button>
+      <type>MV_ADVANCED_X_SETUP_MENU</type>
+      <text>Display Settings</text>
+      <action>EXEC  mythinstall -s advancedX</action>
+   </button>
+
+   <button>
+      <type>MV_ADVANCED_SETUP_MENU</type>
+      <text>Advanced Settings</text>
+      <action>EXEC  mythinstall -s advanced</action>
+   </button>
+
+   <button>
+      <type>MV_AUDIO_SETUP_MENU</type>
+      <text>Audio Settings</text>
+       <action>EXEC  mythinstall -s sound </action>
+   </button>
+
+   <button>
+      <type>MV_ACCESS_SETUP_MENU</type>
+      <text>Access Control</text>
+      <action>EXEC  mythinstall -s accesscontrol </action>
+   </button>
+
+   <button>
+      <type>MV_USER_SETUP_MENU</type>
+      <text>User Accounts</text>
+      <action>EXEC  mythinstall -s user </action>
+   </button>
+
+   <button>
+      <type>MV_WEBACCESS_SETUP_MENU</type>
+      <text>Web Security</text>
+      <action>EXEC  mythinstall -s webuser </action>
+   </button>
+
+   <!--
+   <button>
+      <type>SETUP_MENU</type>
+      <text>Settings Profile Manager</text>
+      <action>EXEC  mythinstall -t </action>
+   </button>
+   -->
+
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/is.xml b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/is.xml
new file mode 100644
index 0000000..88b7e6b
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/is.xml
@@ -0,0 +1,3 @@
+<mythmenu name="Internet Steams">
+
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/library.xml.patch b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/library.xml.patch
new file mode 100644
index 0000000..be06e34
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/library.xml.patch
@@ -0,0 +1,12 @@
+--- themes/defaultmenu/library.xml.orig	2010-11-06 00:39:51.000000000 +0000
++++ themes/defaultmenu/library.xml	2010-11-06 00:44:54.000000000 +0000
+@@ -44,8 +44,7 @@
+         <type>STREAM</type>
+         <text>Play Online Streams</text>
+         <description></description>
+-        <action>PLUGIN mythstream</action>
+-        <depends>mythstream</depends>
++        <action>MENU is.xml</action>
+     </button>
+ 
+     <button>
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/linhes.xml b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/linhes.xml
new file mode 100644
index 0000000..01b6ffa
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/linhes.xml
@@ -0,0 +1,59 @@
+<mythmenu name="LinHES">
+
+    <button>
+        <type>SETUP_GENERAL</type>
+        <text>MythTV Configuration</text>
+        <text lang="IT">Impostazioni</text>
+        <text lang="ES">Configuración</text>
+        <text lang="DE">Zubehör / Konfiguration</text>
+        <text lang="DA">Tilbehør/Indstillinger</text>
+        <text lang="IS">Uppsetning</text>
+        <text lang="NL">Configuratie</text>
+        <text lang="PT">Utensílios</text>
+        <text lang="SV">Verktyg / Inställningar</text>
+        <text lang="JA">設�~Z</text>
+        <text lang="FI">Oheis/Asetukset</text>
+        <text lang="ZH_TW">工�~E�/設�~Z</text>
+        <text lang="SL">Nastavitve</text>
+        <text lang="ET">Utiliidid / sätted</text>
+        <text lang="RU">У�~Bили�~B�~K / �~]а�~A�~B�~@ойки</text>
+        <text lang="AR">تضب�~Jطات</text>
+        <text lang="PL">Narz�~Ydzia / ustawienia</text>
+        <text lang="HE">ע�~Vר�~Y�~] / �~T�~R�~Sר�~Uת</text>
+        <text lang="HU">Eszközök / Beállítások</text>
+        <alttext lang="DE">Verschiedenes</alttext>
+        <alttext lang="SV">Inställningar</alttext>
+        <alttext lang="ET">Sätted</alttext>
+        <alttext lang="RU">�~]а�~A�~B�~@ойки</alttext>
+        <alttext lang="AR">تضب�~Jطات</alttext>
+        <description>Configure MythTV and plugins</description>
+        <description lang="DE">MythTV und Plugins konfigurieren</description>
+        <action>MENU util_menu.xml</action>
+    </button>
+
+   <button>
+     <type>LINHES_SETUP</type>
+     <text>LinHES Configuration</text>
+     <action>MENU HOST_SETTINGS.xml</action>
+   </button>
+
+   <button>
+     <type>BACKUP</type>
+     <text>Backup LinHES</text>
+     <action>MENU mythbackup.xml</action>
+   </button>
+
+   <button>
+     <type>RESTORE</type>
+     <text>Restore LinHES</text>
+     <action>MENU mythrestore.xml</action>
+   </button>
+
+<!--#Check for updates-->
+   <button>
+     <type>UPGRADE</type>
+     <text>Update LinHES</text>
+     <action>MENU update.xml</action>
+   </button>
+<!--#Check for updates-->
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/mainmenu.xml.patch b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/mainmenu.xml.patch
new file mode 100644
index 0000000..0491803
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/mainmenu.xml.patch
@@ -0,0 +1,37 @@
+--- themes/defaultmenu/mainmenu.xml.orig	2010-11-08 22:30:08.000000000 +0000
++++ themes/defaultmenu/mainmenu.xml	2010-11-08 22:35:51.000000000 +0000
+@@ -2,6 +2,13 @@
+ <mythmenu name="MAIN">
+ 
+     <button>
++        <type>TV_WATCH_TV</type>
++        <text>Watch TV</text>
++        <description>Watch live television</description>
++        <action>TV_WATCH_LIVE</action>
++    </button>
++
++    <button>
+         <type>MENU_MEDIA_LIBRARY</type>
+         <text>Media Library</text>
+         <action>MENU library.xml</action>
+@@ -31,17 +38,10 @@
+     </button>
+ 
+     <button>
+-        <type>TV_WATCH_TV</type>
+-        <text>Watch TV</text>
+-        <description>Watch live television</description>
+-        <action>TV_WATCH_LIVE</action>
+-    </button>
+-
+-    <button>
+         <type>MENU_UTILITIES_SETUP</type>
+-        <text>Utilities / Setup</text>
+-        <description>Configure MythTV and plugins</description>
+-        <action>MENU util_menu.xml</action>
++        <text>Service Menu</text>
++        <description>Configure your system</description>
++        <action>MENU linhes.xml</action>
+     </button>
+ 
+ </mythmenu>
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/mythbackup.xml b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/mythbackup.xml
new file mode 100644
index 0000000..5914b33
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/mythbackup.xml
@@ -0,0 +1,20 @@
+<mythmenu name="LinHES">
+
+   <button>
+     <type>BACKUP</type>
+     <text>Do you wish to backup?</text>
+     <action>NONE</action>
+   </button>
+
+   <button>
+     <type>BACKUP</type>
+     <text>Yes</text>
+     <action>EXEC sudo /usr/LH/bin/mythbackup</action>
+   </button>
+   
+   <button>
+     <type>BACKUP</type>
+     <text>No</text>
+     <action>UPMENU</action>
+   </button>
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/mythrestore.xml b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/mythrestore.xml
new file mode 100644
index 0000000..8f5c285
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/mythrestore.xml
@@ -0,0 +1,20 @@
+<mythmenu name="LinHES">
+
+   <button>
+     <type>RESTORE</type>
+     <text>Do you wish to restore?</text>
+     <action>NONE</action>
+   </button>
+
+   <button>
+     <type>RESTORE</type>
+     <text>Yes</text>
+     <action>EXEC sudo /usr/LH/bin/mythrestore</action>
+   </button>
+   
+   <button>
+     <type>BACKUP</type>
+     <text>No</text>
+     <action>UPMENU</action>
+   </button>
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/optical_menu.xml.patch b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/optical_menu.xml.patch
new file mode 100644
index 0000000..143424f
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/optical_menu.xml.patch
@@ -0,0 +1,16 @@
+--- themes/defaultmenu/optical_menu.xml.orig	2010-11-06 00:39:43.000000000 +0000
++++ themes/defaultmenu/optical_menu.xml	2010-11-06 00:42:59.000000000 +0000
+@@ -26,6 +26,13 @@
+     </button>
+ 
+     <button>
++        <type>DVD_RIP</type>
++        <text>Import video files from DVD</text>
++       <description>Import video files from a data DVD</description>
++        <action>EXEC /usr/LH/bin/importfiles.sh</action>
++    </button>
++
++    <button>
+         <type>MUSIC_RIP</type>
+         <text>Import CD</text>
+         <description>Import music from an audio CD</description>
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/original/create_patch.sh b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/original/create_patch.sh
new file mode 100644
index 0000000..34d8b8c
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/original/create_patch.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+for i in *.xml
+do
+	diff -u $i.orig $i > ../$i.patch
+done
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/setup.xml b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/setup.xml
new file mode 100644
index 0000000..f56bb6f
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/setup.xml
@@ -0,0 +1,111 @@
+<mythmenu name="MAIN">
+
+   <button>
+     <type>SETUP_GENERAL</type>
+     <text>1. General</text>
+     <text lang="IT">1. Generale</text>
+     <text lang="PT">1. Geral</text>
+     <text lang="SV">1. Generellt</text>
+     <text lang="JA">1. 一般</text>
+     <text lang="DE">1. Allgemeines</text>
+     <text lang="FI">1. Yleiset</text>
+     <text lang="FR">1. Général</text>
+     <text lang="SI">1. Splošno</text>
+     <text lang="ET">1. Üldine</text>
+     <text lang="NB">1 Generelt</text>
+     <text lang="DK">1. Generelt</text>
+     <text lang="ES">1. General</text>
+     <text lang="CZ">1. Obecný</text>
+     <text lang="RU">1. Общие</text>
+     <action>GENERAL</action>
+   </button>
+
+   <button>
+     <type>SETUP_CAPTURE_CARDS</type>
+     <text>2. Capture cards</text>
+     <text lang="IT">2. Schede di Acquisizione</text>
+     <text lang="PT">2. Placas de Captura</text>
+     <text lang="SV">2. TV-kort</text>
+     <text lang="JA">2. キャプチャカード</text>
+     <text lang="DE">2. TV-Karten</text>
+     <text lang="FI">2. TV-kortit</text>
+     <text lang="FR">2. Cartes d'acquisition</text>
+     <text lang="SI">2. Kartice za zajem</text>
+     <text lang="ET">2. TV-kaardid</text>
+     <text lang="NB">2 TV-kort</text>
+     <text lang="DK">2. TV-kort</text>
+     <text lang="ES">2. Capturadoras</text>
+     <text lang="CZ">2. Zachytávací karty</text>
+     <text lang="RU">2. Карты захвата</text>
+     <action>CAPTURE CARDS</action>
+   </button>
+
+   <button>
+     <type>SETUP_VIDEO_SOURCES</type>
+     <text>3. Video sources</text>
+     <text lang="IT">3. Fonte Video</text>
+     <text lang="PT">3. Fontes de Vídeo</text>
+     <text lang="SV">3. Videokällor</text>
+     <text lang="JA">3. ビデオソース</text>
+     <text lang="DE">3. Videoquellen</text>
+     <text lang="FI">3. Kuvanlähteet</text>
+     <text lang="FR">3. Sources vidéo</text>
+     <text lang="SI">3. Video viri</text>
+     <text lang="ET">3. Videosisendid</text>
+     <text lang="NB">3 Videokilder</text>
+     <text lang="DK">3. Videokilder</text>
+     <text lang="ES">3. Fuentes de Vídeo</text>
+     <text lang="CZ">3. Zdroje obrazu</text>
+     <text lang="RU">3. Видео источники</text>
+     <action>VIDEO SOURCES</action>
+   </button>
+
+   <button>
+     <type>SETUP_INPUT_CONNECTIONS</type>
+     <text>4. Input connections</text>
+     <text lang="IT">4. Connessioni di Ingresso</text>
+     <text lang="PT">4. Ligações de Entrada</text>
+     <text lang="SV">4. Anslutningar</text>
+     <text lang="JA">4. 入力とソースの接続</text>
+     <text lang="DE">4. Verknüpfungen</text>
+     <text lang="FI">4. Sisääntuloasetukset</text>
+     <text lang="FR">4. Entrées Vidéos</text>
+     <text lang="SI">4. Vhodne povezave</text>
+     <text lang="ET">4. Sisendite ühendused</text>
+     <text lang="NB">4 Inndata</text>
+     <text lang="DK">4. Indgange</text>
+     <text lang="ES">4. Conexiones</text>
+     <text lang="CZ">4. Připojení vstupů</text>
+     <text lang="RU">4. Соединение входов</text>
+     <action>CARD INPUTS</action>
+   </button>
+
+   <button>
+     <type>SETUP_CHANNEL_EDITOR</type>
+     <text>5. Channel Editor</text>
+     <text lang="IT">5. Modifica Canali</text>
+     <text lang="SV">5. Kanaleditor</text>
+     <text lang="JA">5. チャンネル設定</text>
+     <text lang="DE">5. Sender bearbeiten</text>
+     <text lang="FI">5. Kanavanviritys</text>
+     <text lang="FR">5. Editeur de chaînes</text>
+     <text lang="SI">5. Urejanje kanalov</text>
+     <text lang="ET">5. Kanaliredaktor</text>
+     <text lang="NB">5 Kanalredigerer</text>
+     <text lang="DK">5. Kanal opsætning</text>
+     <text lang="ES">5. Editor Canales</text>
+     <text lang="CZ">5. Editor kanálů</text>
+     <text lang="RU">5. Редактор каналов</text>
+     <action>CHANNEL EDITOR</action>
+   </button>
+
+   <button>
+     <type>SETUP_STORAGE_GROUPS</type>
+     <text>6. Storage Directories</text>
+     <text lang="IT">6. Cartelle</text>
+     <text lang="FI">Tallennusryhmät</text>
+     <text lang="SV">Lagringsgrupper</text>
+     <action>STORAGE GROUPS</action>
+   </button>
+
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/siriusmenu.xml b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/siriusmenu.xml
new file mode 100644
index 0000000..e317b36
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/siriusmenu.xml
@@ -0,0 +1,419 @@
+<mythmenu name="SIRIUS">
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius Hits 1</text>
+      <action>EXEC /usr/bin/cliSipie siriushits1</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>StarLite</text>
+      <action>EXEC /usr/bin/cliSipie starlite</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius Love</text>
+      <action>EXEC /usr/bin/cliSipie siriuslove</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Movin EZ</text>
+      <action>EXEC /usr/bin/cliSipie movineasy</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius Gold</text>
+      <action>EXEC /usr/bin/cliSipie siriusgold</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>'60s Vibrations</text>
+      <action>EXEC /usr/bin/cliSipie 60svibrations</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Totally '70s</text>
+      <action>EXEC /usr/bin/cliSipie totally70s</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Big '80s</text>
+      <action>EXEC /usr/bin/cliSipie big80s</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>ThePulse</text>
+      <action>EXEC /usr/bin/cliSipie thepulse</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Bridge</text>
+      <action>EXEC /usr/bin/cliSipie thebridge</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>BBC Radio 1</text>
+      <action>EXEC /usr/bin/cliSipie bbcradio1</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Super Shuffle</text>
+      <action>EXEC /usr/bin/cliSipie supershuffle</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Elvis Radio</text>
+      <action>EXEC /usr/bin/cliSipie elvisradio</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Classic Vinyl</text>
+      <action>EXEC /usr/bin/cliSipie classicvinyl</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Classic Rewind</text>
+      <action>EXEC /usr/bin/cliSipie classicrewind</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>TheVault</text>
+      <action>EXEC /usr/bin/cliSipie thevault</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Jam_ON</text>
+      <action>EXEC /usr/bin/cliSipie jamon</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Spectrum</text>
+      <action>EXEC /usr/bin/cliSipie thespectrum</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>BuzzSaw</text>
+      <action>EXEC /usr/bin/cliSipie buzzsaw</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Octane</text>
+      <action>EXEC /usr/bin/cliSipie octane</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Alt Nation</text>
+      <action>EXEC /usr/bin/cliSipie altnation</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>1st Wave</text>
+      <action>EXEC /usr/bin/cliSipie firstwave</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Hair Nation</text>
+      <action>EXEC /usr/bin/cliSipie hairnation</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>'90s Alternative</text>
+      <action>EXEC /usr/bin/cliSipie 90salternative</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Garage</text>
+      <action>EXEC /usr/bin/cliSipie undergroundgarage</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Left of Center</text>
+      <action>EXEC /usr/bin/cliSipie leftofcenter</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Hard Attack</text>
+      <action>EXEC /usr/bin/cliSipie hardattack</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Faction</text>
+      <action>EXEC /usr/bin/cliSipie faction</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Punk</text>
+      <action>EXEC /usr/bin/cliSipie punk</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>The Coffee House</text>
+      <action>EXEC /usr/bin/cliSipie coffeehouse</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Margaritaville</text>
+      <action>EXEC /usr/bin/cliSipie radiomargaritaville</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius Disorder</text>
+      <action>EXEC /usr/bin/cliSipie siriusdisorder</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Reggae</text>
+      <action>EXEC /usr/bin/cliSipie reggaerhythms</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Area 33</text>
+      <action>EXEC /usr/bin/cliSipie area33</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Boombox</text>
+      <action>EXEC /usr/bin/cliSipie boombox</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Chill</text>
+      <action>EXEC /usr/bin/cliSipie chill</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>The Beat</text>
+      <action>EXEC /usr/bin/cliSipie thebeat</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Strobe</text>
+      <action>EXEC /usr/bin/cliSipie thestrobe</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Hip-Hop Nation</text>
+      <action>EXEC /usr/bin/cliSipie hiphopnation</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>BackSpin</text>
+      <action>EXEC /usr/bin/cliSipie backspin</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Shade 45</text>
+      <action>EXEC /usr/bin/cliSipie shade45</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Hot Jamz</text>
+      <action>EXEC /usr/bin/cliSipie hotjamz</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Heart  &amp; Soul</text>
+      <action>EXEC /usr/bin/cliSipie heartandsoul</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>SoulTown</text>
+      <action>EXEC /usr/bin/cliSipie soultown</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>New Country</text>
+      <action>EXEC /usr/bin/cliSipie newcountry</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Prime Country</text>
+      <action>EXEC /usr/bin/cliSipie primecountry</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Roadhouse</text>
+      <action>EXEC /usr/bin/cliSipie theroadhouse</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Outlaw Country</text>
+      <action>EXEC /usr/bin/cliSipie outlawcountry</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Bluegrass</text>
+      <action>EXEC /usr/bin/cliSipie bluegrass</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Spirit</text>
+      <action>EXEC /usr/bin/cliSipie spirit</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Praise</text>
+      <action>EXEC /usr/bin/cliSipie praise</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Planet Jazz</text>
+      <action>EXEC /usr/bin/cliSipie planetjazz</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>JazzCafe</text>
+      <action>EXEC /usr/bin/cliSipie jazzcafe</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>PureJazz</text>
+      <action>EXEC /usr/bin/cliSipie purejazz</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Spa 73</text>
+      <action>EXEC /usr/bin/cliSipie spa73</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Blues</text>
+      <action>EXEC /usr/bin/cliSipie siriusblues</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Siriusly Sinatra</text>
+      <action>EXEC /usr/bin/cliSipie siriuslysinatra</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Broadway's Best</text>
+      <action>EXEC /usr/bin/cliSipie broadwaysbest</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Symphony Hall</text>
+      <action>EXEC /usr/bin/cliSipie symphonyhall</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Met Opera Radio</text>
+      <action>EXEC /usr/bin/cliSipie metropolitanopera</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius Pops</text>
+      <action>EXEC /usr/bin/cliSipie siriuspops</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Universo Latino</text>
+      <action>EXEC /usr/bin/cliSipie universolatino</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Rumbon</text>
+      <action>EXEC /usr/bin/cliSipie rumbon</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Martha Stewart</text>
+      <action>EXEC /usr/bin/cliSipie marthastewartlivingradio</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius Stars</text>
+      <action>EXEC /usr/bin/cliSipie siriusstars</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>OutQ Gay Radio</text>
+      <action>EXEC /usr/bin/cliSipie siriusoutq</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Patriot</text>
+      <action>EXEC /usr/bin/cliSipie siriuspatriot</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Left</text>
+      <action>EXEC /usr/bin/cliSipie siriusleft</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>CNN</text>
+      <action>EXEC /usr/bin/cliSipie cnn</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>wrn</text>
+      <action>EXEC /usr/bin/cliSipie wrn</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Blue Collar Comedy</text>
+      <action>EXEC /usr/bin/cliSipie bluecollarcomedy</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Raw Dog Comedy</text>
+      <action>EXEC /usr/bin/cliSipie rawdog</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Laugh Break Comedy</text>
+      <action>EXEC /usr/bin/cliSipie laughbreak</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>thefoxxhole</text>
+      <action>EXEC /usr/bin/cliSipie thefoxxhole</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>lime</text>
+      <action>EXEC /usr/bin/cliSipie lime</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Kids Stuff</text>
+      <action>EXEC /usr/bin/cliSipie kidsstuff</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Catholic Channel</text>
+      <action>EXEC /usr/bin/cliSipie thecatholicchannel</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>EWTN</text>
+      <action>EXEC /usr/bin/cliSipie ewtnglobal</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>christiantalk</text>
+      <action>EXEC /usr/bin/cliSipie christiantalk</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Sirius NFL Radio</text>
+      <action>EXEC /usr/bin/cliSipie siriusnflradio</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Maxim Radio</text>
+      <action>EXEC /usr/bin/cliSipie maximradio</action>
+   </button>
+   <button>
+      <type>MUSIC</type>
+      <text>Cosmo Radio</text>
+      <action>EXEC /usr/bin/cliSipie cosmopolitanradio</action>
+   </button>
+   <button>
+     <type>TV_DELETE</type>
+     <text>Stop Listening</text>
+     <action>EXEC /usr/bin/sipie_kill</action>
+  </button>
+
+</mythmenu>
+
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/update.xml b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/update.xml
new file mode 100644
index 0000000..d2ac3fe
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/update.xml
@@ -0,0 +1,9 @@
+<mythmenu name="LinHES">
+
+   <button>
+     <type>UPGRADE</type>
+     <text>Check for Updates</text>
+     <action>EXEC sudo /usr/LH/bin/linhes_update.sh</action>
+   </button>
+
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/update2.xml b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/update2.xml
new file mode 100644
index 0000000..64388cb
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/update2.xml
@@ -0,0 +1,20 @@
+<mythmenu name="LinHES">
+
+   <button>
+     <type>UPGRADE</type>
+     <text>Install Updates</text>
+     <action>EXEC sudo /usr/LH/bin/linhes_update2.sh install</action>
+   </button>
+
+   <button>
+     <type>UPGRADE</type>
+     <text>Cancel Updates</text>
+     <action>EXEC sudo /usr/LH/bin/linhes_update2.sh</action>
+   </button>
+
+   <button>
+     <type>UPGRADE</type>
+     <text>View Updates</text>
+     <action>MENU update3.xml</action>
+   </button>
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/util_menu.xml.patch b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/util_menu.xml.patch
new file mode 100644
index 0000000..82d303e
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/util_menu.xml.patch
@@ -0,0 +1,16 @@
+--- themes/defaultmenu/util_menu.xml.orig	2010-11-06 00:40:01.000000000 +0000
++++ themes/defaultmenu/util_menu.xml	2010-11-06 00:45:42.000000000 +0000
+@@ -17,6 +17,13 @@
+     </button>
+ 
+     <button>
++        <type>VIDEO_SCREENSHOOTER</type>
++        <text>Thumbnail Generator</text>
++        <description>Generate thumbnail images for videos</description>
++        <action>EXEC /usr/LH/bin/shootscreens-mythtv.sh</action>
++    </button>
++
++    <button>
+         <type>SETUP_MENU</type>
+         <text>Setup</text>
+         <description>Configure MythTV and plugins</description>
diff --git a/abs/core/mythtv/stable-0.25/mythtv/menu-xml/xmmenu.xml b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/xmmenu.xml
new file mode 100644
index 0000000..6b26d11
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/menu-xml/xmmenu.xml
@@ -0,0 +1,574 @@
+<!-- Current as of April 25, 2007 -->
+<mythmenu name="XM">
+
+	<button>
+		<type>MUSIC</type>
+		<text>The '40s</text>
+		<action>EXEC /usr/bin/xamp kill 4</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The '50s</text>
+		<action>EXEC /usr/bin/xamp kill 5</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The '60s</text>
+		<action>EXEC /usr/bin/xamp kill 6</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The '70s</text>
+		<action>EXEC /usr/bin/xamp kill 7</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The '80s</text>
+		<action>EXEC /usr/bin/xamp kill 8</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The '90s</text>
+		<action>EXEC /usr/bin/xamp kill 9</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>America</text>
+		<action>EXEC /usr/bin/xamp kill 10</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>X Country</text>
+		<action>EXEC /usr/bin/xamp kill 12</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Willie's Place</text>
+		<action>EXEC /usr/bin/xamp kill 13</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Bluegrass Junction</text>
+		<action>EXEC /usr/bin/xamp kill 14</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Village</text>
+		<action>EXEC /usr/bin/xamp kill 15</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Highway 16</text>
+		<action>EXEC /usr/bin/xamp kill 16</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>US Country</text>
+		<action>EXEC /usr/bin/xamp kill 17</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>20 on 20</text>
+		<action>EXEC /usr/bin/xamp kill 20</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Heart</text>
+		<action>EXEC /usr/bin/xamp kill 23</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Blend</text>
+		<action>EXEC /usr/bin/xamp kill 25</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Flight 26</text>
+		<action>EXEC /usr/bin/xamp kill 26</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Cinemagic</text>
+		<action>EXEC /usr/bin/xamp kill 27</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>On Broadway</text>
+		<action>EXEC /usr/bin/xamp kill 28</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>U-Pop</text>
+		<action>EXEC /usr/bin/xamp kill 29</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Hitlist</text>
+		<action>EXEC /usr/bin/xamp kill 30</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Torch</text>
+		<action>EXEC /usr/bin/xamp kill 31</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Message</text>
+		<action>EXEC /usr/bin/xamp kill 32</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Spirit</text>
+		<action>EXEC /usr/bin/xamp kill 33</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>enLighten</text>
+		<action>EXEC /usr/bin/xamp kill 34</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Deep Tracks</text>
+		<action>EXEC /usr/bin/xamp kill 40</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Boneyard</text>
+		<action>EXEC /usr/bin/xamp kill 41</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Liquid Metal</text>
+		<action>EXEC /usr/bin/xamp kill 42</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XMU</text>
+		<action>EXEC /usr/bin/xamp kill 43</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Fred</text>
+		<action>EXEC /usr/bin/xamp kill 44</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Cafe</text>
+		<action>EXEC /usr/bin/xamp kill 45</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Top Tracks</text>
+		<action>EXEC /usr/bin/xamp kill 46</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Ethel</text>
+		<action>EXEC /usr/bin/xamp kill 47</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Squizz</text>
+		<action>EXEC /usr/bin/xamp kill 48</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Big Tracks</text>
+		<action>EXEC /usr/bin/xamp kill 49</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Loft</text>
+		<action>EXEC /usr/bin/xamp kill 50</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Music Lab</text>
+		<action>EXEC /usr/bin/xamp kill 51</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Verge</text>
+		<action>EXEC /usr/bin/xamp kill 52</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Fungus</text>
+		<action>EXEC /usr/bin/xamp kill 53</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Lucy</text>
+		<action>EXEC /usr/bin/xamp kill 54</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Soul Street</text>
+		<action>EXEC /usr/bin/xamp kill 60</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Flow</text>
+		<action>EXEC /usr/bin/xamp kill 61</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Suite 62</text>
+		<action>EXEC /usr/bin/xamp kill 62</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Groove</text>
+		<action>EXEC /usr/bin/xamp kill 64</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Rhyme</text>
+		<action>EXEC /usr/bin/xamp kill 65</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>RAW</text>
+		<action>EXEC /usr/bin/xamp kill 66</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The City</text>
+		<action>EXEC /usr/bin/xamp kill 67</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Heat</text>
+		<action>EXEC /usr/bin/xamp kill 68</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Real Jazz</text>
+		<action>EXEC /usr/bin/xamp kill 70</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Watercolors</text>
+		<action>EXEC /usr/bin/xamp kill 71</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Beyond Jazz</text>
+		<action>EXEC /usr/bin/xamp kill 72</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>High Standards</text>
+		<action>EXEC /usr/bin/xamp kill 73</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Bluesville</text>
+		<action>EXEC /usr/bin/xamp kill 74</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Hear Music</text>
+		<action>EXEC /usr/bin/xamp kill 75</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Fine Tuning</text>
+		<action>EXEC /usr/bin/xamp kill 76</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Audio Visions</text>
+		<action>EXEC /usr/bin/xamp kill 77</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Escape</text>
+		<action>EXEC /usr/bin/xamp kill 78</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>On The Rocks</text>
+		<action>EXEC /usr/bin/xamp kill 79</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Move</text>
+		<action>EXEC /usr/bin/xamp kill 80</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>BPM</text>
+		<action>EXEC /usr/bin/xamp kill 81</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The System</text>
+		<action>EXEC /usr/bin/xamp kill 82</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Chrome</text>
+		<action>EXEC /usr/bin/xamp kill 83</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM-Chill</text>
+		<action>EXEC /usr/bin/xamp kill 84</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Fuego</text>
+		<action>EXEC /usr/bin/xamp kill 90</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Viva</text>
+		<action>EXEC /usr/bin/xamp kill 91</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Aguila</text>
+		<action>EXEC /usr/bin/xamp kill 92</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Caliente</text>
+		<action>EXEC /usr/bin/xamp kill 94</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Luna</text>
+		<action>EXEC /usr/bin/xamp kill 95</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Air Musique</text>
+		<action>EXEC /usr/bin/xamp kill 100</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Joint</text>
+		<action>EXEC /usr/bin/xamp kill 101</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Sur La Route</text>
+		<action>EXEC /usr/bin/xamp kill 102</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>World Zone</text>
+		<action>EXEC /usr/bin/xamp kill 103</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Ngoma</text>
+		<action>EXEC /usr/bin/xamp kill 104</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Classics</text>
+		<action>EXEC /usr/bin/xamp kill 110</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Vox</text>
+		<action>EXEC /usr/bin/xamp kill 112</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Pops</text>
+		<action>EXEC /usr/bin/xamp kill 113</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Kids</text>
+		<action>EXEC /usr/bin/xamp kill 116</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Bob Edwards Show</text>
+		<action>EXEC /usr/bin/xamp kill 133</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>XM Comedy</text>
+		<action>EXEC /usr/bin/xamp kill 150</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Laugh USA</text>
+		<action>EXEC /usr/bin/xamp kill 151</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Special X</text>
+		<action>EXEC /usr/bin/xamp kill 154</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Agenda</text>
+		<action>EXEC /usr/bin/xamp kill 134</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Oprah and Friends</text>
+		<action>EXEC /usr/bin/xamp kill 156</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>The Virus</text>
+		<action>EXEC /usr/bin/xamp kill 202</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>1 Hit Wonders</text>
+		<action>EXEC /usr/bin/xamp kill 300</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Metalcore</text>
+		<action>EXEC /usr/bin/xamp kill 301</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>New Indie First</text>
+		<action>EXEC /usr/bin/xamp kill 302</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Late Night Mix</text>
+		<action>EXEC /usr/bin/xamp kill 303</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Sessions@AOL</text>
+		<action>EXEC /usr/bin/xamp kill 304</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>Shuffle</text>
+		<action>EXEC /usr/bin/xamp kill 305</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>New Rock First</text>
+		<action>EXEC /usr/bin/xamp kill 306</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>New Country First</text>
+		<action>EXEC /usr/bin/xamp kill 307</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>New Hip Hop First</text>
+		<action>EXEC /usr/bin/xamp kill 308</action>
+	</button>
+
+	<button>
+		<type>MUSIC</type>
+		<text>New Pop First</text>
+		<action>EXEC /usr/bin/xamp kill 309</action>
+	</button>
+
+	<button>
+		<type>TV_DELETE</type>
+		<text>Stop Listening</text>
+		<action>EXEC /usr/bin/xamp kill</action>
+	</button>
+
+</mythmenu>
diff --git a/abs/core/mythtv/stable-0.25/mythtv/myth.sh b/abs/core/mythtv/stable-0.25/mythtv/myth.sh
new file mode 100644
index 0000000..fb7122c
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/myth.sh
@@ -0,0 +1,4 @@
+export PATH=$PATH:/usr/local/bin
+# set core file size to 0
+ulimit -c 0
+export MALLOC_CHECK_=0
\ No newline at end of file
diff --git a/abs/core/mythtv/stable-0.25/mythtv/myth_settings.patch b/abs/core/mythtv/stable-0.25/mythtv/myth_settings.patch
new file mode 100644
index 0000000..abdabfe
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/myth_settings.patch
@@ -0,0 +1,1816 @@
+diff --git a/mythtv/libs/libmythbase/mythcorecontext.cpp b/mythtv/libs/libmythbase/mythcorecontext.cpp
+index ad58f59..809d662 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)
++{
++    return d->m_database->export_settings(src_hostname,
++                                          saved_settingsgroupname,
++                                          table_list);
++}
++
++//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..db3bbb9 100644
+--- a/mythtv/libs/libmythbase/mythcorecontext.h
++++ b/mythtv/libs/libmythbase/mythcorecontext.h
+@@ -168,6 +168,39 @@ 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);
++    //END JM ADDED
++
+   private:
+     MythCoreContextPrivate *d;
+ 
+diff --git a/mythtv/libs/libmythbase/mythdb.cpp b/mythtv/libs/libmythbase/mythdb.cpp
+index ea30783..730fc3e 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,901 @@ 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");
++        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");
++    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");
++    }
++
++    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";
++
++    if ( settings_check ( dest_hostname , saved_settingsgroupname ) )
++    {
++        MSqlQuery query(MSqlQuery::InitCon());
++        QStringList::Iterator it;
++        QString current_table;
++        if ( table_list.isEmpty() )
++        {
++            table_list.append("settings");
++            table_list.append("keybindings");
++        }
++
++        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;
++
++            // 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 = 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();
++           }
++       }
++   }
++
++}; //end import_settings
++
++QMap<QString, QMap<QString,QString> >
++            MythDB::export_settings(QString src_hostname,
++                                    QString saved_settingsgroupname,
++                                    QStringList table_list)
++{
++    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");
++    }
++
++    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;
++            }
++        }
++
++        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")
++        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..fe3c91c 100644
+--- a/mythtv/libs/libmythbase/mythdb.h
++++ b/mythtv/libs/libmythbase/mythdb.h
+@@ -75,6 +75,48 @@ 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);
++
++    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 7f00e50..03f1792 100644
+--- a/mythtv/programs/mythutil/commandlineparser.cpp
++++ b/mythtv/programs/mythutil/commandlineparser.cpp
+@@ -114,6 +114,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
+@@ -136,6 +167,55 @@ 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");
++
++    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");
++
++
++
++
+     // 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 774528f..5be3ec7 100644
+--- a/mythtv/programs/mythutil/mythutil.pro
++++ b/mythtv/programs/mythutil/mythutil.pro
+@@ -3,6 +3,7 @@ include ( ../../version.pro )
+ include ( ../programs-libs.pro )
+ 
+ QT += network sql
++QT += xml
+ 
+ TEMPLATE = app
+ CONFIG += thread
+@@ -10,7 +11,7 @@ TARGET = mythutil
+ target.path = $${PREFIX}/bin
+ INSTALLS = target
+ 
+-LIBS += $$EXTRA_LIBS 
++LIBS += $$EXTRA_LIBS
+ INCLUDEPATH += ../../libs/libmythbase
+ 
+ QMAKE_CLEAN += $(TARGET)
+@@ -19,8 +20,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..ed3c9a3
+--- /dev/null
++++ b/mythtv/programs/mythutil/settingsutils.cpp
+@@ -0,0 +1,541 @@
++// 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_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;
++            value_pair_map[record_element.nodeName()] = record_element.text();
++        }
++            //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;
++    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;
++
++    if (cmdline.toBool("table_list"))
++    {
++        tablestring = QString(cmdline.toString("table_list"));
++        table_list = tablestring.split(",", QString::SkipEmptyParts);
++    }
++    else
++        table_list << "settings" <<"keybindings" ;
++
++    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);
++
++    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
++                {
++                    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);
diff --git a/abs/core/mythtv/stable-0.25/mythtv/mythbackend b/abs/core/mythtv/stable-0.25/mythtv/mythbackend
new file mode 100644
index 0000000..93773a2
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/mythbackend
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+. /etc/rc.conf
+. /etc/rc.d/functions
+
+PID=`pidof -o %PPID /usr/bin/mythbackend`
+case "$1" in
+  start)
+    stat_busy "Starting MythTV Backend"
+    [ ! -e /var/run/mysqld.pid ] && echo -n "mysqld not started" && stat_fail && exit
+    [ -z "$PID" ] && /usr/bin/mythbackend -d -l /var/log/mythbackend.log -v important 
+    if [ $? -gt 0 ]; then
+      stat_fail
+    else
+      echo $PID > /var/run/mythbackend.pid
+      add_daemon mythbackend
+      stat_done
+    fi
+    ;;
+  stop)
+    stat_busy "Stopping MythTV Backend"
+    [ ! -z "$PID" ]  && kill $PID &>/dev/null
+    if [ $? -gt 0 ]; then
+      stat_fail
+    else
+      rm_daemon mythbackend
+      stat_done
+    fi
+    ;;
+  restart)
+    $0 stop
+    sleep 1s 
+    $0 start
+    ;;
+  *)
+    echo "usage: $0 {start|stop|restart}"
+esac
+exit 0
diff --git a/abs/core/mythtv/stable-0.25/mythtv/mythbackend.lr b/abs/core/mythtv/stable-0.25/mythtv/mythbackend.lr
new file mode 100644
index 0000000..4f218bc
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/mythbackend.lr
@@ -0,0 +1,9 @@
+/var/log/mythtv/mythbackend.log {
+	copytruncate
+	daily
+	size 10M
+	missingok
+	rotate 7
+	compress
+	notifempty
+}
diff --git a/abs/core/mythtv/stable-0.25/mythtv/mythbackend.sh b/abs/core/mythtv/stable-0.25/mythtv/mythbackend.sh
new file mode 100644
index 0000000..e7a7b70
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/mythbackend.sh
@@ -0,0 +1,117 @@
+#!/bin/bash
+#
+#	/etc/rc.d/init.d/mythbackend
+#
+# Starts the mythbackend as a daemon
+#
+# chkconfig: 345 90 10
+# description: Starts the mythbackend process as a daemon after the XWindows \
+#              system is started, in runlevel 5. This allows scheduled \
+#              recordings to occur without manual intervention.
+# processname: mythbackend
+
+# Copyright (c) by Michael Thomson <linux at m-thomson dot net>
+# With thanks to Stu Tomlinson <stu at nosnilmot dot com>
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+# Default values to use if none are supplied in the config file.
+# User who should start the mythbackend processes
+MBE_USER="root"
+# Directory holding the mythbackend binary
+MBE_LOCATION="/usr/local/bin/"
+# Name of mythbackend binary
+MBE_PROG="mythbackend"
+# Full path to mythbackend log file
+MBE_LOGFILE="/var/log/mythtv/mythbackend.log"
+
+# Source function library.
+. /etc/init.d/functions
+
+# Source config file if available
+if [ -f "/etc/sysconfig/mythbackend" ]; then
+  . /etc/sysconfig/mythbackend
+fi
+
+test -x ${MBE_LOCATION}${MBE_PROG} || exit 0
+
+RETVAL=0
+
+#
+#	See how we were called.
+#
+
+start() {
+	# Check if mythbackend is already running
+	if [ ! -f /var/lock/subsys/${MBE_PROG} ]; then
+	    echo -n "Starting ${MBE_PROG}: "
+	    # /usr/local/bin/mythbackend -d -l /some/log/file
+	    #daemon --user ${MBE_USER} ${MBE_LOCATION}${MBE_PROG} -d -l ${MBE_LOGFILE}
+	    ${MBE_LOCATION}${MBE_PROG} -d -l ${MBE_LOGFILE}
+	    RETVAL=$?
+	    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/${MBE_PROG}
+	    echo
+	fi
+	return $RETVAL
+}
+
+stop() {
+	echo -n "Stopping ${MBE_PROG}: "
+	killproc ${MBE_LOCATION}${MBE_PROG}
+	RETVAL=$?
+	[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/${MBE_PROG}
+	echo
+        return $RETVAL
+}
+
+
+restart() {
+	stop
+	start
+}	
+
+reload() {
+	restart
+}	
+
+status_at() {
+ 	status ${MBE_LOCATION}${MBE_PROG}
+}
+
+case "$1" in
+start)
+	start
+	;;
+stop)
+	stop
+	;;
+reload|restart)
+	restart
+	;;
+condrestart)
+	if [ -f /var/lock/subsys/${MBE_PROG} ]; then
+	    restart
+	fi
+	;;
+status)
+	status_at
+	;;
+*)
+	echo "Usage: $0 {start|stop|restart|condrestart|status}"
+	exit 1
+esac
+
+exit $?
+exit $RETVAL
diff --git a/abs/core/mythtv/stable-0.25/mythtv/mythfrontend.lr b/abs/core/mythtv/stable-0.25/mythtv/mythfrontend.lr
new file mode 100644
index 0000000..1580533
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/mythfrontend.lr
@@ -0,0 +1,9 @@
+/var/log/mythtv/mythfrontend.log {
+	copytruncate
+	daily
+	size 10M
+	missingok
+	rotate 7
+	compress
+	notifempty
+}
diff --git a/abs/core/mythtv/stable-0.25/mythtv/mythtv.install b/abs/core/mythtv/stable-0.25/mythtv/mythtv.install
new file mode 100644
index 0000000..3f2e304
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/mythtv.install
@@ -0,0 +1,63 @@
+# arg 1:  the new package version
+post_install() {
+	if [ ! -d /var/log/mythtv ]
+	then
+		mkdir -p /var/log/mythv
+		chown -R mythtv /var/log/mythtv
+		echo "---" > /var/log/mythtv/mythbackend.log
+		chown mythtv /var/log/mythtv/mythbackend.log
+	fi
+	ln -s /usr/share/mythtv/themes/defaultmenu/is.xml /usr/share/mythtv/is.xml
+}
+
+pre_upgrade() {
+	if [ ! -L /usr/share/mythtv/is.xml ]
+	then
+		mv /usr/share/mythtv/is.xml /usr/share/mythtv/is.xml.pre
+	else
+		mv /usr/share/mythtv/themes/defaultmenu/is.xml /usr/share/mythtv/themes/defaultmenu/is.xml.pre
+	fi
+}
+
+post_upgrade() {
+	if [ ! -d /var/log/mythtv ]
+	then
+		mkdir -p /var/log/mythv
+		chown -R mythtv /var/log/mythtv
+	fi
+	if [ -e /usr/share/mythtv/is.xml.pre ]
+	then
+		rm -fr /usr/share/mythtv/themes/defaultmenu/is.xml
+		mv /usr/share/mythtv/is.xml.pre /usr/share/mythtv/themes/defaultmenu/is.xml
+		ln -s /usr/share/mythtv/themes/defaultmenu/is.xml /usr/share/mythtv/is.xml
+	else
+		mv /usr/share/mythtv/themes/defaultmenu/is.xml.pre /usr/share/mythtv/themes/defaultmenu/is.xml
+	fi
+	pacxmbc=`pacman -Q xbmc`
+    if [ -z "$pacxbmc" ]
+	then
+		mv /usr/share/mythtv/themes/defaultmenu/library.xml /tmp
+		grep -v -e /mythmenu /tmp/library.xml > /tmp/library.xml.tmp
+		echo "<!--#XBMC-->" >> /tmp/library.xml.tmp
+		echo "   <button>" >> /tmp/library.xml.tmp
+		echo "     <type>MENU_XBMC</type>" >> /tmp/library.xml.tmp
+		echo "     <text>Launch XBMC</text>" >> /tmp/library.xml.tmp
+		echo "     <action>EXEC /usr/bin/xbmc</action>" >> /tmp/library.xml.tmp 
+		echo "   </button>" >> /tmp/library.xml.tmp
+		echo "<!--#XBMC-->" >> /tmp/library.xml.tmp
+		echo "" >> /tmp/library.xml.tmp
+		echo "</mythmenu>" >> /tmp/library.xml.tmp
+		mv /tmp/library.xml.tmp /usr/share/mythtv/themes/defaultmenu/library.xml
+	fi
+}
+
+
+# arg 1:  the old package version
+post_remove() {
+	/bin/true
+
+}
+
+op=$1
+shift
+$op $*
diff --git a/abs/core/mythtv/stable-0.25/mythtv/pretty b/abs/core/mythtv/stable-0.25/mythtv/pretty
new file mode 100644
index 0000000..7e0ab21
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/pretty
@@ -0,0 +1,9 @@
+#!/bin/bash
+if [ -f /usr/share/mythtv/contrib/user_jobs/mythlink.pl ]
+then
+        su - mythtv -c "perl /usr/share/mythtv/contrib/user_jobs/mythlink.pl --link /myth/pretty"
+elif [ -f /usr/share/mythtv/contrib/user_jobs/mythrename.pl ]
+then
+        su - mythtv -c "perl /usr/share/mythtv/contrib/user_jobs/mythrename.pl --link /myth/pretty"
+fi
+
diff --git a/abs/core/mythtv/stable-0.25/mythtv/smolt_jump.patch b/abs/core/mythtv/stable-0.25/mythtv/smolt_jump.patch
new file mode 100644
index 0000000..76f884c
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythtv/smolt_jump.patch
@@ -0,0 +1,10 @@
+--- programs/mythfrontend/networkcontrol.cpp.orig	2010-11-08 23:07:04.000000000 +0000
++++ programs/mythfrontend/networkcontrol.cpp	2010-11-08 23:08:06.000000000 +0000
+@@ -88,6 +88,7 @@
+     jumpMap["zoneminderliveview"]    = "ZoneMinder Live View";
+     jumpMap["zoneminderevents"]      = "ZoneMinder Events";
+     jumpMap["snapshot"]              = "ScreenShot";
++    jumpMap["mythsmolt"]             = "MythSmolt";
+ 
+     jumpMap["channelrecpriority"]    = "Channel Recording Priorities";
+     jumpMap["viewscheduled"]         = "Manage Recordings / Fix Conflicts";
diff --git a/abs/core/mythtv/stable-0.25/mythweb/PKGBUILD b/abs/core/mythtv/stable-0.25/mythweb/PKGBUILD
new file mode 100644
index 0000000..cab8fbd
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythweb/PKGBUILD
@@ -0,0 +1,46 @@
+pkgname=mythweb
+pkgver=0.24
+pkgrel=16
+pkgdesc="Web interface for MythTV's backend"
+url="http://www.mythtv.org"
+license="GPL"
+arch=('i686' 'x86_64')
+
+depends=('mythtv>=0.24' 'lighttpd' 'php' 'local-website')
+groups=('mythtv-extras')
+
+patches=()
+source=('ftp://ftp.knoppmyth.net/R6/sources/mythweb-0.24-fixes.tar.bz2' `echo ${patches[@]:0}`)
+
+DOCROOT=/data/srv/httpd/htdocs/mythweb
+_gitroot="https://github.com/mythtv/mythweb.git"
+_gitname="${pkgname}"
+build() {
+
+	cd $startdir/src/mythweb
+	git pull
+
+	echo "--------------------------applying patches----------------------------------------------------"
+	for i in `echo ${patches[@]:0} `
+	do
+		echo applying $i
+		echo "-----------------------------"
+		patch -Np0  -i ${srcdir}/$i  || return 1
+	done
+	echo "--------------------------done applying patches-----------------------------------------------"
+	
+	[ "$CARCH" = "i686"   ] && ARCH="i686"
+	[ "$CARCH" = "x86_64" ] && ARCH="x86-64"
+
+	mkdir -p $startdir/pkg/$DOCROOT/{image_cache,php_sessions,data}
+        rsync -arp --exclude .git --delete-excluded  $startdir/src/mythweb/* $startdir/pkg/$DOCROOT
+	rm $startdir/pkg/$DOCROOT/README
+	chown -R http:http $startdir/pkg/$DOCROOT
+	chmod g+rw $pkgdir/$DOCROOT/{image_cache,php_sessions,data}
+
+        # mythweb modules_path fix for 0.24
+        # http://code.mythtv.org/trac/ticket/9255
+        cd ${pkgdir}/${DOCROOT}
+        ln -s modules modules_path
+}
+md5sums=('45703fa3899c4ee84d1b087bfcc6654e')
diff --git a/abs/core/mythtv/stable-0.25/mythweb/mythweb.php.patch b/abs/core/mythtv/stable-0.25/mythweb/mythweb.php.patch
new file mode 100644
index 0000000..4525e68
--- /dev/null
+++ b/abs/core/mythtv/stable-0.25/mythweb/mythweb.php.patch
@@ -0,0 +1,11 @@
+--- mythweb.php.orig	2011-02-01 03:33:56.000000000 +0000
++++ mythweb.php	2011-02-01 03:34:20.000000000 +0000
+@@ -30,7 +30,7 @@
+     if (Modules::getModule($Path[0])) {
+     // Add the current module directory to our search path, so modules can
+     // define includes, etc.
+-        ini_set('include_path', ini_get('include_path').':'.modules_path.'/'.$Path[0]);
++        ini_set('include_path', ini_get('include_path').':'.modules.'/'.$Path[0]);
+     // Load the module handler
+         require_once 'handler.php';
+     }
-- 
cgit v0.12