← Back to team overview

mythbuntu-dev team mailing list archive

[Merge] lp:~tgm4883/mythbuntu/mythbuntu-common into lp:~mythbuntu-dev/mythbuntu/mythbuntu-common

 

Thomas Mashos has proposed merging lp:~tgm4883/mythbuntu/mythbuntu-common into lp:~mythbuntu-dev/mythbuntu/mythbuntu-common.

Requested reviews:
  mythbuntu-dev (mythbuntu-dev)

For more details, see:
https://code.launchpad.net/~tgm4883/mythbuntu/mythbuntu-common/+merge/51059

Added scheduling functionality to mythbuntu-bare
-- 
https://code.launchpad.net/~tgm4883/mythbuntu/mythbuntu-common/+merge/51059
Your team mythbuntu-dev is requested to review the proposed merge of lp:~tgm4883/mythbuntu/mythbuntu-common into lp:~mythbuntu-dev/mythbuntu/mythbuntu-common.
=== added directory 'bare'
=== added file 'bare/backup-task.py'
--- bare/backup-task.py	1970-01-01 00:00:00 +0000
+++ bare/backup-task.py	2011-02-24 02:29:55 +0000
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+
+from mythbackup import Backup
+import ConfigParser
+
+CONFIGFILENAME = "mythbuntu-bare-client.conf"
+CONFIGPATH = "/etc/default/"
+CONFIGFILE = CONFIGPATH+CONFIGFILENAME
+
+## Read config file
+config = ConfigParser.ConfigParser()
+config.read(CONFIGFILE)
+
+## Check if managed and if so, then update
+managed = config.get("General", "managed")
+if managed:
+  pipe = subprocess.Popen(["/usr/share/mythbuntu-bare/update-task.py"], stdout=subprocess.PIPE).communicate()
+
+## Reread config file in case it was updated
+config.read(CONFIGFILE)
+DB = config.get("Backup", "database")
+storagedir = config.get("Backup", "storagedir")
+
+## Run backup job
+Backup().backup_job(DB, storagedir)
+
+

=== added file 'bare/mythbackup.py'
--- bare/mythbackup.py	1970-01-01 00:00:00 +0000
+++ bare/mythbackup.py	2011-02-24 02:29:55 +0000
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+
+import os
+import tarfile
+import time
+import shutil
+import subprocess
+import platform
+
+class Backup():
+
+    def backup_job(self, BackupDB=True, Location="/var/lib/mythtv/bare"):
+        """Backup all the files"""
+        ## Check backup directory exists
+        if not os.path.exists(Location):
+            os.makedirs(Location)
+        ## Array of files to Backup
+        BACKUPFILES = [
+        "/etc/mythtv/config.xml",
+        "/etc/mythtv/mysql.txt",
+        "/etc/lirc/lircd.conf",
+        "/etc/lirc/hardware.conf",
+        "/etc/hostname",
+        "/etc/hosts",
+        ]
+        USER=os.getenv("HOME")
+        BACKUPFILES.append(USER+"/.lirc")
+        ## Set up backup location
+        TMPDIR="/tmp/mythbuntu-bare"
+        if not os.path.exists(TMPDIR):
+            os.makedirs(TMPDIR)
+        BACKUPFILES.append(TMPDIR)
+        ## Set status file
+        STATUSFILE="/tmp/mythbuntu-bare-status"
+        if os.path.isfile(STATUSFILE):
+            os.remove(STATUSFILE)
+        timestamp=time.strftime("%Y%m%d-%H%M", time.localtime())
+        ## Backup database only if told to do so
+        DBB=""
+        MBE=""
+        if os.path.isfile("/usr/share/doc/mythtv-backend-master"):
+          MBE="_MBE"
+          DBB="_NODB"
+          if BackupDB == True:
+            #Run DB Backup
+            os.system("echo '20\nBacking up database (this could take a few minutes)'>"+STATUSFILE)
+            backupscript="/usr/share/mythtv/mythconverg_backup.pl"
+            pipe = subprocess.Popen([backupscript, '--directory', TMPDIR], stdout=subprocess.PIPE).communicate()
+            DBB="_YESDB"
+        ## Setup for final tar file
+        hostname = platform.node()
+        tarfilename=Location+'/mythbuntu-system-backup_'+hostname+'_'+timestamp+MBE+DBB+'.tar.gz'
+        TF=tarfile.open(tarfilename,mode='w:gz')
+        os.system("echo '90\nZipping up files'>"+STATUSFILE)
+	## Add files to tarball
+        for item in BACKUPFILES:
+            if os.path.exists(item):
+              TF.add(item)
+        TF.close()
+        ## Remove tmp Backup directory and status file
+        if os.path.exists(TMPDIR):
+            shutil.rmtree(TMPDIR)
+        if os.path.isfile(STATUSFILE):
+            os.remove(STATUSFILE)
+

=== added file 'bare/mythbareupdate.py'
--- bare/mythbareupdate.py	1970-01-01 00:00:00 +0000
+++ bare/mythbareupdate.py	2011-02-24 02:29:55 +0000
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+
+import ConfigParser
+import os
+import shutil
+import hashlib
+
+CONFIGFILENAME = "mythbuntu-bare-client.conf"
+CONFIGPATH = "/etc/mythbuntu-bare/"
+
+CHECKSUMFILE = "/tmp/CHECKSUM"
+CONFIGFILE = CONFIGPATH+CONFIGFILENAME
+TMPCONFIGFILE = "/tmp/"+CONFIGFILENAME
+
+class Update():
+
+  def update_job(self, ServerIP=None):
+    if os.path.isfile(CONFIGFILE):
+      NEW = False
+      config = ConfigParser.ConfigParser()
+      config.read(CONFIGFILE)
+      self.Revision = config.get("General", "Revision")
+      ServerIP = config.get("General", "ServerIP")
+      ServerURL = "http://"+ServerIP+"/mythbuntu-bare/";
+    else:
+      NEW = True
+      self.Revision = 0
+      ServerURL = "http://"+ServerIP+"/mythbuntu-bare/";
+
+    ## Check tmp dir for update file
+    if os.path.isfile(TMPCONFIGFILE):
+      NEW = False
+      self.process_updates()
+      os.remove(TMPCONFIGFILE)
+
+    ## Download update file from server
+    download_successful=False
+    try:
+      self.check_server(CONFIGFILENAME,ServerURL)
+      self.check_server("CHECKSUM",ServerURL)
+      download_successful=True
+    except:
+      print "ERROR: Couldn't update files from server"
+
+    ## If files downloaded from server, get revision and process them
+    if download_successful:
+      if NEW == False:
+        config = ConfigParser.ConfigParser()
+        config.read(CONFIGFILE)
+        Revision = config.get("General", "Revision")
+      else:
+        NEW = False
+        Revision = 0
+      self.process_updates()
+
+    ## Remove temp files
+    if os.path.isfile(TMPCONFIGFILE):
+      os.remove(TMPCONFIGFILE)
+    if os.path.isfile("/tmp/CHECKSUM"):
+      os.remove("/tmp/CHECKSUM")
+
+  def check_server(self,file_name,base_url):
+    from urllib2 import Request, urlopen, URLError, HTTPError
+    #create the url and the request
+    url = base_url + file_name
+    req = Request(url)
+    # Open the url
+    f = urlopen(req)
+    # Open our local file for writing
+    local_file = open("/tmp/"+file_name, "w")
+    #Write to our local file
+    local_file.write(f.read())
+    local_file.close()
+
+  def process_updates(self):
+    ## Get revision
+    tempconfig = ConfigParser.ConfigParser()
+    tempconfig.read(TMPCONFIGFILE)
+    tempRevision = tempconfig.get("General", "Revision")
+    ## If revision is newer, process. 
+    if int(self.Revision) < int(tempRevision):
+      ## Calculate checksum
+      m = hashlib.md5()
+      f = open(TMPCONFIGFILE)
+      for line in f:
+        m.update(line)
+      calcsum = m.hexdigest()
+      f.close()
+      chksumconfig = ConfigParser.ConfigParser()
+      chksumconfig.read(CHECKSUMFILE)
+      checksum = chksumconfig.get("Checksum", "md5")
+      if calcsum == checksum:
+        ## If checksums match, copy file into dir
+        shutil.copyfile(TMPCONFIGFILE, CONFIGFILE)
+      else:
+        print "Error: Checksum failed"
+
+#Update().update_job("192.168.0.41")
+
+

=== added file 'bare/mythrestore.py'
--- bare/mythrestore.py	1970-01-01 00:00:00 +0000
+++ bare/mythrestore.py	2011-02-24 02:29:55 +0000
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+import shutil
+import os
+import tarfile
+
+class Restore():
+
+    def restore_job(self, Location, RestoreDB):
+        USER=os.getenv("HOME")
+        ## Set temp directory and status file
+        TMPDIR="/tmp/mythbuntu-bare/"
+        STATUSFILE="/tmp/mythbuntu-bare-status"
+        ##Remove temp DB dir and statusfile first in case it already exists
+        if os.path.exists(STATUSFILE):
+            os.remove(STATUSFILE)
+        if os.path.exists(TMPDIR):
+            shutil.rmtree(TMPDIR)
+        ## Open and Extract tarfile
+        os.system("echo '30\nRestoring configuration files'>"+STATUSFILE)
+        TF=tarfile.open(Location,mode='r')
+        TF.extractall(path="/", members=None)
+        TF.close()
+        ## Update mythtv db password with backed up password
+        os.system("DEBIAN_FRONTEND=noninteractive dpkg-reconfigure mythtv-database")
+        if os.path.isfile("/usr/share/doc/mythtv-backend-master"):
+          if RestoreDB == True:
+            print "Yes we are restoring the database!"
+            os.system("echo '40\nRestoring database (this could take a few minutes)'>"+STATUSFILE)
+            ##TODO
+            restorescript="/usr/share/mythtv/mythconverg_restore.pl"
+            pipe = subprocess.Popen([restorescript, '--drop_database', '--create_database', '--directory', TMPDIR], stdout=subprocess.PIPE).communicate()
+        ## Remove Temp directory and status file
+        os.system("echo '90\nCleaning up temp files'>"+STATUSFILE)
+        time.sleep(1)
+        if os.path.exists(TMPDIR):
+            shutil.rmtree(TMPDIR)
+        if os.path.exists(STATUSFILE):
+            os.remove(STATUSFILE)
+

=== added file 'bare/update-task.py'
--- bare/update-task.py	1970-01-01 00:00:00 +0000
+++ bare/update-task.py	2011-02-24 02:29:55 +0000
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+from mythbareupdate import Update
+
+## Update from server. Managed is checked in other file
+Update().update_job()  
+

=== added file 'bare/updater.py'
--- bare/updater.py	1970-01-01 00:00:00 +0000
+++ bare/updater.py	2011-02-24 02:29:55 +0000
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+
+
+class CronUpdater():
+
+    def generate_cron_schedule(self):
+      import ConfigParser
+      config = ConfigParser.ConfigParser()
+      config.read("/etc/mythbuntu-bare/mythbuntu-bare-client.conf")
+      managed = config.get("General", "managed")
+      schedule = config.get("Backup", "schedule")
+      day = config.get("Backup", "day")
+      hour = config.get("Backup", "hour")
+      minute = config.get("Backup", "minute")
+      weekday = config.get("Backup", "weekday")
+      f = open("/etc/cron.d/mythbuntu-bare","w")
+      if not schedule == "disabled":
+        f.write(minute+" "+hour+" "+day+" "+"*"+" "+weekday+" root /usr/share/mythbuntu-bare/backup-task.py\n")
+      if managed == True:
+        f.write("41 * * * * root /usr/share/mythbuntu-bare/update-task.py\n")
+      f.close()

=== modified file 'debian/changelog'
--- debian/changelog	2011-02-08 08:31:30 +0000
+++ debian/changelog	2011-02-24 02:29:55 +0000
@@ -1,3 +1,9 @@
+mythbuntu-common (0.56-0ubuntu2) UNRELEASED; urgency=low
+
+  * Added scheduling functionality to -bare
+
+ -- Thomas Mashos <tgm4883@xxxxxxxxx>  Wed, 23 Feb 2011 17:43:23 -0800
+
 mythbuntu-common (0.56-0ubuntu1) natty; urgency=low
 
   * Add basic support for QR codes to install Android or iOS apps for remote.

=== modified file 'debian/install'
--- debian/install	2010-02-16 06:51:09 +0000
+++ debian/install	2011-02-24 02:29:55 +0000
@@ -1,1 +1,2 @@
 debian/mythbuntu.make usr/share/mythbuntu
+bare usr/share/mythbuntu

=== modified file 'plugins/python/mythbuntu-bare.py' (properties changed: -x to +x)
--- plugins/python/mythbuntu-bare.py	2010-09-15 15:34:09 +0000
+++ plugins/python/mythbuntu-bare.py	2011-02-24 02:29:55 +0000
@@ -28,13 +28,19 @@
 import shutil
 import subprocess
 from threading import Thread
+import sys
+import ConfigParser
+sys.path.append("/usr/share/mythbuntu/bare")
+from mythbackup import Backup
+from mythrestore import Restore
+
 
 class MythbuntuBaRePlugin(MCCPlugin):
     """A Plugin to assist in backing up and restoring the mythtv DB"""
     #
     #Load GUI & Calculate Changes
     #
-    CONFIGFILE = "/etc/default/mythbuntu-bare"
+    CONFIGFILE = "/etc/mythbuntu-bare/mythbuntu-bare-client.conf"
 
     USER=os.getenv("HOME")
 
@@ -43,7 +49,7 @@
     "/etc/mythtv/mysql.txt",
     "/etc/lirc/lircd.conf",
     "/etc/lirc/hardware.conf",
-    "/etc/udev/rules.d",
+    "/etc/udev/rules.d"
     ]
 
     BACKUPFILES.append(USER+"/.lirc")
@@ -53,6 +59,7 @@
     restore_file = '/tmp'
 
     IsTarFile = False
+    ValidNewConf = False
 
     def __init__(self):
         #Initialize parent class
@@ -69,12 +76,31 @@
            and stores it into the plugin's own internal structures"""
         import os
         self.changes = {}
-        self.changes['backup_schedule'] = os.path.exists('/etc/cron.daily/mythbuntu-bare')
         if os.path.exists(self.CONFIGFILE):
+          try:
             self.config.read(self.CONFIGFILE)
-            self.changes['BackupLocation'] = self.config.get("Backup", "BackupLocation")
+            self.changes['serverip'] = self.config.get("General", "serverip")
+            self.changes['managed'] = self.config.get("General", "managed")
+            if str.lower(self.changes['managed']) == "true":
+              self.managed_label.set_text("This machine is current in managed mode")
+              self.radio_convert.set_sensitive(False)
+              self.backup_schedule.set_sensitive(False)
+            self.changes['BackupLocation'] = self.config.get("Backup", "storagedir")
+            self.changes['backup_db'] = self.config.get("Backup", "db")
+            self.changes['backup_schedule'] = self.config.get("Backup", "schedule")
+            self.changes['backup_schedule_day'] = self.config.get("Backup", "day")
+            self.changes['backup_schedule_hour'] = self.config.get("Backup", "hour")
+            self.changes['backup_schedule_minute'] = self.config.get("Backup", "minute")
+            self.changes['backup_schedule_weekday'] = self.config.get("Backup", "weekday")
+            self.db_backup_checkbutton.set_active(int(self.config.get("Backup", "db")))
+          except:
+            print "Error: Could not read config file"
+          if not self.query_installed('mythtv-backend-master'):
+            self.backup_db_label.set_text("Database can only be backed up from master backend")
+            self.db_backup_checkbutton.set_sensitive(False)
+            self.db_backup_checkbutton.set_active(False)
         else:
-            self.changes['BackupLocation'] = "NOWHERE"
+          print "Error: Config file not found"
 
     def applyStateToGUI(self):
         """Takes the current state information and sets the GUI
@@ -96,27 +122,45 @@
         self.radio_restore.set_active(False)
         self.backup_now.set_active(False)
         self.backup_dir_button.set_active(False)
-        self.on_radio_backup_toggled(None)
+#        self.on_radio_backup_toggled(None)
         self.on_backup_dir_button_toggled(None)
 #        self.on_backup_schedule_toggled(None)
-        if self.changes['backup_schedule']:
-            self.scheduled_label.set_text("Enabled")
-        else:
-            self.scheduled_label.set_text("Disabled")
-        if self.query_installed('mythtv-backend-master') == True:
-            self.db_backup_checkbutton.set_active(True)
-        else:
-            self.db_backup_checkbutton.set_active(False)
+        if self.changes['backup_schedule'] == "disabled":
+          self.scheduled_label.set_text("Disabled")
+          self.schedule_disabled_button.set_active(True)
+        elif self.changes['backup_schedule'] == "daily":
+          self.schedule_daily_button.set_active(True)
+        elif self.changes['backup_schedule'] == "weekly":
+          self.schedule_weekly_button.set_active(True)
+          wday = int(self.changes['backup_schedule_weekday'])
+          self.weekly_combobox.set_active(wday)
+          self.hbox_schedule_weekly.show()
+        elif self.changes['backup_schedule'] == "monthly":
+          self.schedule_monthly_button.set_active(True)
+          md = int(self.changes['backup_schedule_day'])
+          mday = md-1
+          self.monthly_combobox.set_active(mday)
+          self.hbox_schedule_monthly.show()
+        if not self.changes['backup_schedule'] == "disabled":
+          shour = self.changes['backup_schedule_hour']
+          self.schedule_hour_combobox.set_active(int(shour))
+          smin = int(self.changes['backup_schedule_minute'])/5
+          self.schedule_minute_combobox.set_active(int(smin))
         self.restore_label_isfile.hide()
+        self.managed_label_isfile.hide()
         ## Filter only tar.gz files for restore
         filter = gtk.FileFilter()
         filter.set_name("Backup Files")
         filter.add_pattern("*.tar.gz")
         self.restore_file.add_filter(filter)
         self.restore_file.unselect_all()
+        conffilter = gtk.FileFilter()
+        conffilter.set_name("Config Files")
+        conffilter.add_pattern("*.conf")
+        self.managedfilechooser.add_filter(conffilter)
+        self.managedfilechooser.unselect_all()
         self.backup_location.unselect_all()
         ## Disable non-implemented items
-        self.backup_schedule.hide()
         self.backup_u1_button.hide()
         self.backup_dropbox_button.hide()
         self.backup_dir_button.hide() ## Only disabled since no other locations are available
@@ -125,44 +169,37 @@
         """Determines what items have been modified on this plugin"""
         MCCPlugin.clearParentState(self)
         if self.radio_backup.get_active():
-#            print "BACKUP"
             if self.backup_dir_button.get_active():
                 self.BACKUP_LOCATION=self.backup_location.get_filename()
-            elif self.backup_u1_button.get_active():
-                #TODO
-                print "U1 Location"
-            elif self.backup_dropbox_button.get_active():
-                #TODO
-                print "Dropbox Location"
+            self.BACKUP_DB = self.db_backup_checkbutton.get_active()
             if self.backup_now.get_active():
                 self._markReconfigureUser('Backup Now',self.BACKUP_LOCATION)
             elif self.backup_schedule.get_active():
                 #TODO
-                self._markReconfigureRoot('Save Backup Location',self.BACKUP_LOCATION)
-                if self.BACKUP_LOCATION != self.changes['BackupLocation']:
-                    self._markReconfigureRoot('backup_location',True)
-                    self._markReconfigureRoot('backup_schedule',True)
-#                if self.backup_schedule_status.get_active() != self.changes['backup_schedule']:
-#                    self._markReconfigureRoot('backup_schedule',self.backup_schedule_status.get_active())
-#                    print "schedule only"
-            if self.db_backup_checkbutton.get_active() == True:
-                self.BACKUP_DB = True
-            else:
-                self.BACKUP_DB = False
+                if self.schedule_disabled_button.get_active():
+                  self._markReconfigureRoot('Backup Schedule', False)
+                else:
+                  self._markReconfigureRoot('Backup Schedule', True)
+                  self._markReconfigureRoot('Backup Hour', self.schedule_hour_combobox.get_active_text())
+                  self._markReconfigureRoot('Backup Minute', self.schedule_minute_combobox.get_active_text())
+                  self._markReconfigureRoot('Backup Location', self.BACKUP_LOCATION)
+                  self._markReconfigureRoot('Backup Database', self.db_backup_checkbutton.get_active())
+                  if self.schedule_daily_button.get_active():
+                    self._markReconfigureRoot('Backup Daily', True)
+                  elif self.schedule_weekly_button.get_active():
+                    self._markReconfigureRoot('Backup Weekly', self.weekly_combobox.get_active())
+                  elif self.schedule_monthly_button.get_active():
+                    self._markReconfigureRoot('Backup Monthly', self.monthly_combobox.get_active_text())
         if self.radio_restore.get_active():
             self._markReconfigureRoot('restore',self.restore_file.get_filename())
             self._markReconfigureRoot('restore_db',self.restore_db.get_active())
+        if self.radio_convert.get_active():
+            self._markReconfigureRoot('convert',self.managedfilechooser.get_filename())
 
     #
     # Callbacks
     #
 
-#    def on_backup_schedule_toggled(self,widget,data=None):
-        #TODO
-#        print "Populate setup data"
-#        if self.changes['BackupLocation'] != "NOWHERE":
-#            self.backup_location.set_filename(self.changes['BackupLocation'])
-
     def on_restore_file_selection_changed(self,widget,data=None):
         if self.restore_file.get_filename():
             tarfilename=self.restore_file.get_filename()
@@ -181,8 +218,31 @@
             else:
                 self.restore_label_isfile.show()
 
+    def on_managedfilechooser_selection_changed(self,widget,data=None):
+        if self.managedfilechooser.get_filename():
+            newconfigfilename=self.managedfilechooser.get_filename()
+            try:
+                self.newconfig = ConfigParser.ConfigParser()
+                self.newconfig.read(newconfigfilename)
+                self.changes['serverip'] = newconfig.get("General", "serverip")
+                self.changes['managed'] = newconfig.get("General", "managed")
+                self.changes['BackupLocation'] = newconfig.get("Backup", "storagedir")
+                self.changes['backup_db'] = newconfig.get("Backup", "db")
+                self.changes['backup_schedule_day'] = newconfig.get("Backup", "day")
+                self.changes['backup_schedule_hour'] = newconfig.get("Backup", "hour")
+                self.changes['backup_schedule_minute'] = newconfig.get("Backup", "minute")
+                self.changes['backup_schedule_weekday'] = newconfig.get("Backup", "weekday")
+                self.changes['backup_schedule'] = newconfig.get("Backup", "schedule")
+                self.ValidNewConf = True
+                self.managed_label_isfile.hide()
+            except:
+                self.ValidNewConf = False
+                self.managed_label_isfile.show()
+
     def on_button_started_clicked(self,widget,data=None):
+        self.tab_history=[]
         self.CUR_TAB = "vbox_choices"
+        self.tab_history.append("vbox_start")
         self.vbox_start.hide()
         self.vbox_choices.show()
         self.button_box.show()
@@ -192,106 +252,123 @@
         self.change_tab(self.CUR_TAB,"next")
 
     def on_back_button_clicked(self,widget,data=None):
-        self.change_tab(self.CUR_TAB,"back")
+        self.hide_tabs()
+        if self.CUR_TAB == "vbox_final":
+          self.next_button.set_sensitive(True)
+        self.CUR_TAB = self.tab_history.pop()
+        f = getattr(self, self.CUR_TAB)
+        f.show()
+        if self.CUR_TAB == "vbox_start":
+          self.button_box.hide()
 
     def change_tab(self,CURRENT,DIRECTION):
         """Monkee around to display the correct wizard page"""
         self.hide_tabs()
         if self.CUR_TAB == "vbox_choices":
             if self.radio_backup_default_off.get_active() == False:
-                if DIRECTION == "back":
-                    self.CUR_TAB = "vbox_start"
-                    self.vbox_start.show()
-                    self.button_box.hide()
-                elif DIRECTION == "next":
-                    if self.radio_backup.get_active():
-                        self.CUR_TAB = "vbox_backup_choice"
-                        self.vbox_backup_choice.show()
-                    else:
-                        self.CUR_TAB = "vbox_restore"
-                        self.vbox_restore.show()
+                self.tab_history.append(self.CUR_TAB)
+                if self.radio_backup.get_active():
+                    self.CUR_TAB = "vbox_backup_choice"
+                    self.vbox_backup_choice.show()
+                elif self.radio_convert.get_active():
+                    self.CUR_TAB = "vbox_managed_convert"
+                    self.vbox_managed_convert.show()
+                else:
+                    self.CUR_TAB = "vbox_restore"
+                    self.vbox_restore.show()
             else:
                 self.vbox_choices.show()
         elif self.CUR_TAB == "vbox_backup_choice":
-            if DIRECTION == "back":
-                self.CUR_TAB = "vbox_choices"
-                self.vbox_choices.show()
-            elif DIRECTION == "next":
-                if self.backup_now.get_active():
-                    self.CUR_TAB = "vbox_backup_location"
-                    self.vbox_backup_location.show()
-                    self.backup_type = "now"
-                elif self.backup_schedule.get_active():
-                    self.CUR_TAB = "vbox_backup_schedule"
-                    self.vbox_backup_schedule.show()
-                    self.backup_type = "scheduled"
-                else:
-                    self.vbox_backup_choice.show()
+            self.tab_history.append(self.CUR_TAB)
+            if self.backup_now.get_active():
+                self.CUR_TAB = "vbox_backup_location"
+                self.vbox_backup_location.show()
+                self.backup_type = "now"
+            elif self.backup_schedule.get_active():
+                self.CUR_TAB = "vbox_set_schedule"
+                self.vbox_set_schedule.show()
+                self.backup_type = "scheduled"
+            else:
+                self.vbox_backup_choice.show()
         elif self.CUR_TAB == "vbox_restore":
-            if DIRECTION == "back":
-                self.CUR_TAB = "vbox_choices"
-                self.vbox_choices.show()
-            elif DIRECTION == "next":
-                if self.IsTarFile == True:
-                    if self.RESTORE_DB_EXISTS:
-                        self.CUR_TAB = "vbox_restore_db"
-                        self.vbox_restore_db.show()
-                    else:
-                        self.CUR_TAB = "vbox_final"
-                        self.vbox_final.show()
-                        self.next_button.set_sensitive(False)
+            if self.IsTarFile == True:
+                self.tab_history.append(self.CUR_TAB)
+                if self.RESTORE_DB_EXISTS:
+                    self.CUR_TAB = "vbox_restore_db"
+                    self.vbox_restore_db.show()
                 else:
-                    self.vbox_restore.show()
+                    self.CUR_TAB = "vbox_final"
+                    self.vbox_final.show()
+                    self.next_button.set_sensitive(False)
+            else:
+                self.vbox_restore.show()
         elif self.CUR_TAB == "vbox_restore_db":
-            if DIRECTION == "back":
-                self.CUR_TAB = "vbox_restore"
-                self.vbox_restore.show()
-            elif DIRECTION == "next":
-                self.CUR_TAB = "vbox_final"
-                self.vbox_final.show()
-                self.next_button.set_sensitive(False)
+            self.tab_history.append(self.CUR_TAB)
+            self.CUR_TAB = "vbox_final"
+            self.vbox_final.show()
+            self.next_button.set_sensitive(False)
         elif self.CUR_TAB == "vbox_backup_location":
-            if DIRECTION == "back":
-                if self.backup_type == "now":
-                    self.CUR_TAB = "vbox_backup_choice"
-                    self.vbox_backup_choice.show()
-                elif self.backup_type == "scheduled":
-                    self.CUR_TAB = "vbox_backup_schedule"
-                    self.vbox_backup_schedule.show()
-            elif DIRECTION == "next":
+            self.tab_history.append(self.CUR_TAB)
+            self.CUR_TAB = "vbox_final"
+            self.vbox_final.show()
+            self.next_button.set_sensitive(False)
+        elif self.CUR_TAB == "vbox_set_schedule":
+            if self.schedule_daily_button.get_active() or (self.schedule_monthly_button.get_active() and not self.monthly_combobox.get_active_text() == None) or (self.schedule_weekly_button.get_active() and not self.weekly_combobox.get_active_text() == None):
+              self.tab_history.append(self.CUR_TAB)
+              self.CUR_TAB = "vbox_backup_location"
+              self.vbox_backup_location.show()
+#              self.next_button.set_sensitive(False)
+        elif self.CUR_TAB == "vbox_managed_convert":
+            if self.ValidNewConf == True:
+                self.tab_history.append(self.CUR_TAB)
                 self.CUR_TAB = "vbox_final"
                 self.vbox_final.show()
                 self.next_button.set_sensitive(False)
-        elif self.CUR_TAB == "vbox_backup_schedule":
-            if DIRECTION == "back":
-                self.CUR_TAB = "vbox_backup_choice"
-                self.vbox_backup_choice.show()
-            elif DIRECTION == "next":
-                self.CUR_TAB = "vbox_backup_location"
-                self.vbox_backup_location.show()
-        elif self.CUR_TAB == "vbox_final":
-            if DIRECTION == "back":
-                self.next_button.set_sensitive(True)
-                if self.radio_backup.get_active():
-                    self.CUR_TAB = "vbox_backup_location"
-                    self.vbox_backup_location.show()
-                else:
-                    if self.RESTORE_DB_EXISTS:
-                        self.CUR_TAB = "vbox_restore_db"
-                        self.vbox_restore_db.show()
-                    else:
-                        self.CUR_TAB = "vbox_restore"
-                        self.vbox_restore.show()
-
-    def on_radio_backup_toggled(self,widget,data=None):
-        """Show backup or restore settings depeding on user input"""
-        was_selected = self.radio_backup.get_active()
-#        if was_selected:
-#            self.vbox_backup.show()
-#            self.vbox_restore.hide()
-#        else:          
-#            self.vbox_backup.hide()
-#            self.vbox_restore.show()
+            else:
+                self.vbox_managed_convert.show()
+
+    def backup_setter(self,widget,data=None):
+        radio_convert = self.radio_convert.get_active()
+        radio_restore = self.radio_restore.get_active()
+        radio_backup = self.radio_backup.get_active()
+        self.set_final_label()
+
+    def schedule_setter(self,widget,data=None):
+        self.hbox_schedule.hide()
+        self.hbox_schedule_weekly.hide()
+        self.hbox_schedule_monthly.hide()
+        self.monthly_text_label.hide()
+        self.monthly_the_label.hide()
+        self.schedule_label_sent.hide()
+        texthour = self.schedule_hour_combobox.get_active_text()
+        textminute = self.schedule_minute_combobox.get_active_text()
+        if self.schedule_weekly_button.get_active():
+          self.schedule_label_sent.show()
+          self.hbox_schedule.show()
+          self.hbox_schedule_weekly.show()
+          self.schedule_label_sent.set_text("Scheduled backup will be set to run weekly on "+str(self.weekly_combobox.get_active_text())+" at "+texthour+":"+textminute)
+        elif self.schedule_monthly_button.get_active():
+          self.schedule_label_sent.show()
+          self.monthly_text_label.show()
+          self.monthly_the_label.show()
+          self.hbox_schedule.show()
+          self.hbox_schedule_monthly.show()
+          self.schedule_label_sent.set_text("Scheduled backup will be set to run monthly on the "+str(self.monthly_combobox.get_active_text())+" day at "+texthour+":"+textminute)
+        elif self.schedule_daily_button.get_active():
+          self.schedule_label_sent.show()
+          self.schedule_label_sent.set_text("Scheduled backup will be set to run daily at "+texthour+":"+textminute)
+        self.set_final_label()
+
+    def set_final_label(self):
+        if self.radio_convert.get_active():
+          self.job_label.set_text("Please click apply to convert the machine to managed mode")
+        if self.radio_restore.get_active():
+          self.job_label.set_text("Please click apply to perform the restore procedure")
+        if self.radio_backup.get_active():
+          if self.backup_schedule.get_active():
+            self.job_label.set_text("Please click apply to perform the specified scheduling changes")
+          else:
+            self.job_label.set_text("Please click apply to perform the backup procedure")
 
     def on_backup_dir_button_toggled(self,widget,data=None):
         """Prompt user for save location if needed"""
@@ -323,11 +400,19 @@
         self.vbox_backup_choice.hide()
         self.vbox_backup_location.hide()
         self.vbox_final.hide()
+        self.vbox_set_schedule.hide()
+        self.vbox_managed_convert.hide()
 
     def hide_all(self):
         """Hide everything before showing what is needed"""
         self.preconfigured_label.hide()
         self.backup_location.hide()
+        self.hbox_schedule.hide()
+        self.hbox_schedule_weekly.hide()
+        self.hbox_schedule_monthly.hide()
+        self.monthly_text_label.hide()
+        self.monthly_the_label.hide()
+        self.schedule_label_sent.hide()
 
     #
     # Process selected activities
@@ -345,40 +430,61 @@
             if item == "Save Backup Location":
                 self.BACKUP_LOCATION = reconfigure[item]
         for item in reconfigure:
-            if item == "backup_location":
-                self.emit_progress("Setting to 40 percent as a root", 40)
-                time.sleep(2)
-                self.config.set("Backup", "backuplocation", self.BACKUP_LOCATION)
-                with open('/etc/default/mythbuntu-bare', 'wb') as configfile:
-                    self.config.write(configfile)
-            if item == "backup_schedule":
-                #TODO
-                if reconfigure[item]:
-                    self.emit_progress("Setting to 60 percent as a root", 60)
-                    time.sleep(2)
-                    file = open('/etc/cron.daily/mythbuntu-bare', "w")
-                    location = self.BACKUP_LOCATION
-                    self.emit_progress("Setting to 80 percent as a root", 80)
-                    time.sleep(2) 
-                    #TODO
-                    file.writelines("Testing"+location)
-                    file.close()
-                else:
-                    import os
-                    os.remove('/etc/cron.daily/mythbuntu-bare')
+            if item == "Backup Schedule":
+                if reconfigure[item] == False:
+                  self.emit_progress("Removing scheduled job", 50)
+                  if os.path.isfile("/etc/cron.d/mythbuntu-bare"):
+                    os.remove("/etc/cron.d/mythbuntu-bare")
+                elif reconfigure[item] == True:
+                  CONFIGFILE = "/etc/mythbuntu-bare/mythbuntu-bare-client.conf"
+                  import ConfigParser
+                  config = ConfigParser.ConfigParser()
+                  config.add_section('General')
+                  config.add_section('Backup')
+                  config.set('General', 'serverip', '127.0.0.1')
+                  config.set('General', 'managed', 'false')
+                  config.set('General', 'revision', '1')
+                  for item in reconfigure:
+                    if item == 'Backup Hour':
+                      config.set('Backup', 'hour', reconfigure[item])
+                    if item == 'Backup Minute':
+                      config.set('Backup', 'minute', reconfigure[item])
+                    if item == 'Backup Location':
+                      config.set('Backup', 'storagedir', reconfigure[item])
+                    if item == 'Backup Database':
+                      config.set('Backup', 'db', reconfigure[item])
+                    if item == 'Backup Daily':
+                      config.set('Backup', 'schedule', 'daily')
+                      config.set('Backup', 'day', '*')
+                      config.set('Backup', 'weekday', '*')
+                    if item == 'Backup Weekly':
+                      config.set('Backup', 'schedule', 'weekly')
+                      config.set('Backup', 'day', '*')
+                      config.set('Backup', 'weekday', reconfigure[item])
+                    if item == 'Backup Monthly':
+                      config.set('Backup', 'schedule', 'monthly')
+                      config.set('Backup', 'day', reconfigure[item])
+                      config.set('Backup', 'weekday', '*')
+                  with open(CONFIGFILE, 'wb') as conffile:
+                    config.write(conffile)
+                  sys.path.append("/usr/share/mythbuntu/bare")
+                  from updater import CronUpdater
+                  CronUpdater().generate_cron_schedule()
             if item == "restore":
                 RESTORE_LOCATION=reconfigure[item]
                 RESTORE_SET=True
             if item == "restore_db":
                 RESTORE_DB=reconfigure[item]
                 RESTORE_DB_SET=True
-#        print "Restore DB Set: "
-#        print RESTORE_DB_SET
-#        print "Restore Set: "
-#        print RESTORE_SET
+            if item == "convert":
+                PATH=reconfigure[item]
+                try:
+                  shutil.move(PATH, "/etc/mythbuntu-bare/mythbuntu-bare-client.conf")
+                except:
+                  print "Unable to import file"
         if RESTORE_SET == True and RESTORE_DB_SET == True:
             #TODO
-            rj = Thread(target=self.restore_job, args=(RESTORE_LOCATION,RESTORE_DB))
+            rj = Thread(target=Restore().restore_job, args=(RESTORE_LOCATION,RESTORE_DB))
             rj.start()
             self.emit_progress("Restoring files", 20)
             time.sleep(2)
@@ -403,83 +509,6 @@
             self.emit_progress("Restore Job Complete", 100)
         time.sleep(2)
 
-    def backup_job(self, Location, BackupDB):
-        """Backup all the files"""
-        ## Check backup directory exists
-        if not os.path.exists(Location):
-            os.makedirs(Location)
-        ## Array of files to Backup
-        BACKUPFILES = [
-        "/etc/mythtv/config.xml",
-        "/etc/mythtv/mysql.txt",
-        "/etc/lirc/lircd.conf",
-        "/etc/lirc/hardware.conf",
-        "/etc/hostname",
-        "/etc/hosts",
-        ]
-        USER=os.getenv("HOME")
-        BACKUPFILES.append(USER+"/.lirc")
-        ## Set up backup location
-        TMPDIR="/tmp/mythbuntu-bare"
-        if not os.path.exists(TMPDIR):
-            os.makedirs(TMPDIR)
-        BACKUPFILES.append(TMPDIR)
-        ## Set status file
-        STATUSFILE="/tmp/mythbuntu-bare-status"
-        if os.path.isfile(STATUSFILE):
-            os.remove(STATUSFILE)
-        timestamp=time.strftime("%Y%m%d-%H%M", time.localtime())
-        ## Backup database only if told to do so
-        if BackupDB == True:
-            #Run DB Backup
-            os.system("echo '20\nBacking up database (this could take a few minutes)'>"+STATUSFILE)
-            backupscript="/usr/share/mythtv/mythconverg_backup.pl"
-            pipe = subprocess.Popen([backupscript, '--directory', TMPDIR], stdout=subprocess.PIPE).communicate()
-        ## Setup for final tar file
-        tarfilename=Location+'/mythbuntu-system-backup-'+timestamp+'.tar.gz'
-        TF=tarfile.open(tarfilename,mode='w:gz')
-        os.system("echo '90\nZipping up files'>"+STATUSFILE)
-	## Add files to tarball
-        for item in BACKUPFILES:
-            if os.path.exists(item):
-              TF.add(item)
-        TF.close()
-        ## Remove tmp Backup directory and status file
-        if os.path.exists(TMPDIR):
-            shutil.rmtree(TMPDIR)
-        if os.path.isfile(STATUSFILE):
-            os.remove(STATUSFILE)
-
-    def restore_job(self, Location, RestoreDB):
-        USER=os.getenv("HOME")
-        ## Set temp directory and status file
-        TMPDIR="/tmp/mythbuntu-bare/"
-        STATUSFILE="/tmp/mythbuntu-bare-status"
-        ##Remove temp DB dir and statusfile first in case it already exists
-        if os.path.exists(STATUSFILE):
-            os.remove(STATUSFILE)
-        if os.path.exists(TMPDIR):
-            shutil.rmtree(TMPDIR)
-        ## Open and Extract tarfile
-        os.system("echo '30\nRestoring configuration files'>"+STATUSFILE)
-        TF=tarfile.open(Location,mode='r')
-        TF.extractall(path="/", members=None)
-        TF.close()
-        ## Update mythtv db password with backed up password
-        os.system("DEBIAN_FRONTEND=noninteractive dpkg-reconfigure mythtv-database")
-        if RestoreDB == True:
-            print "Yes we are restoring the database!"
-            os.system("echo '40\nRestoring database (this could take a few minutes)'>"+STATUSFILE)
-            ##TODO
-            restorescript="/usr/share/mythtv/mythconverg_restore.pl"
-            pipe = subprocess.Popen([restorescript, '--drop_database', '--create_database', '--directory', TMPDIR], stdout=subprocess.PIPE).communicate()
-        ## Remove Temp directory and status file
-        os.system("echo '90\nCleaning up temp files'>"+STATUSFILE)
-        time.sleep(1)
-        if os.path.exists(TMPDIR):
-            shutil.rmtree(TMPDIR)
-        if os.path.exists(STATUSFILE):
-            os.remove(STATUSFILE)
 
     def user_scripted_changes(self,reconfigure):
         """Local changes that can be performed by the user account.
@@ -488,7 +517,7 @@
         for item in reconfigure:
             if item == "Backup Now":
                 STATUSFILE = "/tmp/mythbuntu-bare-status"
-                bj = Thread(target=self.backup_job, args=(self.BACKUP_LOCATION,self.BACKUP_DB))
+                bj = Thread(target=Backup().backup_job, args=(self.BACKUP_DB,self.BACKUP_LOCATION))
                 bj.start()
                 self.emit_progress("Starting Backup", 10)
                 time.sleep(2)

=== modified file 'plugins/ui/tab_mythbuntu-bare.ui'
--- plugins/ui/tab_mythbuntu-bare.ui	2010-09-14 15:53:24 +0000
+++ plugins/ui/tab_mythbuntu-bare.ui	2011-02-24 02:29:55 +0000
@@ -33,6 +33,7 @@
     </child>
     <child>
       <object class="GtkVBox" id="vbox11">
+        <property name="height_request">400</property>
         <property name="visible">True</property>
         <property name="spacing">10</property>
         <child>
@@ -80,6 +81,8 @@
             </child>
           </object>
           <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
             <property name="position">0</property>
           </packing>
         </child>
@@ -94,7 +97,7 @@
                   <object class="GtkLabel" id="label4">
                     <property name="visible">True</property>
                     <property name="xalign">0</property>
-                    <property name="label" translatable="yes">Would you like to perform a backup or restore?</property>
+                    <property name="label" translatable="yes">What would you like to do?</property>
                   </object>
                 </child>
               </object>
@@ -123,7 +126,7 @@
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
                             <property name="draw_indicator">True</property>
-                            <signal name="toggled" handler="on_radio_backup_toggled"/>
+                            <signal name="toggled" handler="backup_setter"/>
                           </object>
                         </child>
                       </object>
@@ -145,6 +148,7 @@
                             <property name="receives_default">False</property>
                             <property name="draw_indicator">True</property>
                             <property name="group">radio_backup</property>
+                            <signal name="toggled" handler="backup_setter"/>
                           </object>
                         </child>
                       </object>
@@ -153,17 +157,36 @@
                       </packing>
                     </child>
                     <child>
+                      <object class="GtkAlignment" id="alignment42">
+                        <property name="visible">True</property>
+                        <child>
+                          <object class="GtkRadioButton" id="radio_convert">
+                            <property name="label" translatable="yes">Convert to managed client</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="active">True</property>
+                            <property name="draw_indicator">True</property>
+                            <property name="group">radio_backup</property>
+                            <signal name="toggled" handler="backup_setter"/>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
                       <object class="GtkRadioButton" id="radio_backup_default_off">
                         <property name="label" translatable="yes">Default OFF</property>
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="receives_default">False</property>
-                        <property name="active">True</property>
                         <property name="draw_indicator">True</property>
                         <property name="group">radio_backup</property>
                       </object>
                       <packing>
-                        <property name="position">2</property>
+                        <property name="position">3</property>
                       </packing>
                     </child>
                   </object>
@@ -173,8 +196,27 @@
                 <property name="position">1</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkAlignment" id="alignment50">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="xscale">0</property>
+                <property name="left_padding">50</property>
+                <child>
+                  <object class="GtkLabel" id="managed_label">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">This machine is currently in unmanaged mode.</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
           </object>
           <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
             <property name="position">1</property>
           </packing>
         </child>
@@ -218,6 +260,7 @@
                             <property name="receives_default">False</property>
                             <property name="active">True</property>
                             <property name="draw_indicator">True</property>
+                            <signal name="toggled" handler="backup_setter"/>
                           </object>
                         </child>
                       </object>
@@ -232,12 +275,13 @@
                         <property name="left_padding">10</property>
                         <child>
                           <object class="GtkRadioButton" id="backup_schedule">
-                            <property name="label" translatable="yes">Configure scheduled daily backup</property>
+                            <property name="label" translatable="yes">Configure scheduled backup</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
                             <property name="draw_indicator">True</property>
                             <property name="group">backup_now</property>
+                            <signal name="toggled" handler="backup_setter"/>
                           </object>
                         </child>
                       </object>
@@ -268,6 +312,8 @@
             </child>
           </object>
           <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
             <property name="position">2</property>
           </packing>
         </child>
@@ -303,7 +349,7 @@
                     <child>
                       <object class="GtkLabel" id="scheduled_label2">
                         <property name="visible">True</property>
-                        <property name="label" translatable="yes">Daily Backup is currrently: </property>
+                        <property name="label" translatable="yes">Scheduled backup is currrently: </property>
                       </object>
                     </child>
                   </object>
@@ -393,6 +439,8 @@
             </child>
           </object>
           <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
             <property name="position">3</property>
           </packing>
         </child>
@@ -436,6 +484,8 @@
             </child>
           </object>
           <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
             <property name="position">4</property>
           </packing>
         </child>
@@ -459,20 +509,6 @@
               </packing>
             </child>
             <child>
-              <object class="GtkAlignment" id="alignment28">
-                <property name="visible">True</property>
-                <child>
-                  <object class="GtkLabel" id="restore_label_isfile">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">Error: The file you selected is not a valid tar.gz</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
               <object class="GtkAlignment" id="alignment24">
                 <property name="visible">True</property>
                 <property name="xalign">0</property>
@@ -489,11 +525,32 @@
                 </child>
               </object>
               <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkAlignment" id="alignment28">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="xscale">0</property>
+                <property name="top_padding">10</property>
+                <property name="bottom_padding">10</property>
+                <property name="left_padding">10</property>
+                <child>
+                  <object class="GtkLabel" id="restore_label_isfile">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Error: The file you selected is not a valid backup file or is corrupt.</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
                 <property name="position">2</property>
               </packing>
             </child>
           </object>
           <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
             <property name="position">5</property>
           </packing>
         </child>
@@ -599,6 +656,7 @@
                     <property name="visible">True</property>
                     <property name="action">select-folder</property>
                     <property name="title" translatable="yes">Select Storage Location</property>
+                    <property name="width_chars">20</property>
                   </object>
                 </child>
               </object>
@@ -644,8 +702,27 @@
                 <property name="position">4</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkAlignment" id="alignment31">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="left_padding">60</property>
+                <child>
+                  <object class="GtkLabel" id="backup_db_label">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">( Master backend detected on this machine )</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">5</property>
+              </packing>
+            </child>
           </object>
           <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
             <property name="position">6</property>
           </packing>
         </child>
@@ -655,8 +732,11 @@
             <child>
               <object class="GtkAlignment" id="alignment9">
                 <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="xscale">0</property>
+                <property name="left_padding">25</property>
                 <child>
-                  <object class="GtkLabel" id="label1">
+                  <object class="GtkLabel" id="job_label">
                     <property name="visible">True</property>
                     <property name="label" translatable="yes">Please click apply to perform the backup/restore procedure</property>
                   </object>
@@ -668,14 +748,435 @@
             </child>
           </object>
           <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
             <property name="position">7</property>
           </packing>
         </child>
         <child>
+          <object class="GtkVBox" id="vbox_set_schedule">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkAlignment" id="alignment32">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="xscale">0</property>
+                <child>
+                  <object class="GtkLabel" id="label9">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Please set your backup schedule below</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkAlignment" id="alignment33">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="xscale">0</property>
+                <property name="left_padding">25</property>
+                <child>
+                  <object class="GtkHBox" id="hbox6">
+                    <property name="visible">True</property>
+                    <child>
+                      <object class="GtkRadioButton" id="schedule_daily_button">
+                        <property name="label" translatable="yes">Daily</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
+                        <signal name="toggled" handler="schedule_setter"/>
+                      </object>
+                      <packing>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRadioButton" id="schedule_weekly_button">
+                        <property name="label" translatable="yes">Weekly</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                        <property name="group">schedule_daily_button</property>
+                        <signal name="toggled" handler="schedule_setter"/>
+                      </object>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRadioButton" id="schedule_monthly_button">
+                        <property name="label" translatable="yes">Monthly</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="draw_indicator">True</property>
+                        <property name="group">schedule_daily_button</property>
+                        <signal name="toggled" handler="schedule_setter"/>
+                      </object>
+                      <packing>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRadioButton" id="schedule_disabled_button">
+                        <property name="label" translatable="yes">Disabled</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="relief">none</property>
+                        <property name="active">True</property>
+                        <property name="draw_indicator">True</property>
+                        <property name="group">schedule_daily_button</property>
+                      </object>
+                      <packing>
+                        <property name="position">3</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkVBox" id="vbox1">
+                <property name="visible">True</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment38">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xscale">0</property>
+                    <child>
+                      <object class="GtkHBox" id="hbox7">
+                        <property name="visible">True</property>
+                        <child>
+                          <object class="GtkAlignment" id="alignment37">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="xscale">0</property>
+                            <property name="left_padding">25</property>
+                            <property name="right_padding">10</property>
+                            <child>
+                              <object class="GtkLabel" id="label10">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes">Time</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkAlignment" id="alignment36">
+                            <property name="visible">True</property>
+                            <child>
+                              <object class="GtkComboBox" id="schedule_hour_combobox">
+                                <property name="visible">True</property>
+                                <property name="model">liststore3</property>
+                                <property name="active">0</property>
+                                <signal name="changed" handler="schedule_setter"/>
+                                <child>
+                                  <object class="GtkCellRendererText" id="renderer4"/>
+                                  <attributes>
+                                    <attribute name="text">0</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label11">
+                            <property name="visible">True</property>
+                            <property name="label" translatable="yes">:</property>
+                          </object>
+                          <packing>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkAlignment" id="alignment35">
+                            <property name="visible">True</property>
+                            <child>
+                              <object class="GtkComboBox" id="schedule_minute_combobox">
+                                <property name="visible">True</property>
+                                <property name="model">liststore4</property>
+                                <property name="active">0</property>
+                                <signal name="changed" handler="schedule_setter"/>
+                                <child>
+                                  <object class="GtkCellRendererText" id="renderer3"/>
+                                  <attributes>
+                                    <attribute name="text">0</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">3</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkAlignment" id="alignment39">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xscale">0</property>
+                    <property name="left_padding">25</property>
+                    <child>
+                      <object class="GtkHBox" id="hbox_schedule">
+                        <property name="visible">True</property>
+                        <child>
+                          <object class="GtkAlignment" id="alignment34">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="xscale">0</property>
+                            <property name="right_padding">5</property>
+                            <child>
+                              <object class="GtkLabel" id="label12">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Backup on</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkAlignment" id="alignment46">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="xscale">0</property>
+                            <property name="right_padding">5</property>
+                            <child>
+                              <object class="GtkLabel" id="monthly_the_label">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes">the</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkHBox" id="hbox_schedule_weekly">
+                            <property name="visible">True</property>
+                            <child>
+                              <object class="GtkAlignment" id="alignment40">
+                                <property name="visible">True</property>
+                                <child>
+                                  <object class="GtkComboBox" id="weekly_combobox">
+                                    <property name="visible">True</property>
+                                    <property name="model">liststore1</property>
+                                    <property name="active">0</property>
+                                    <signal name="changed" handler="schedule_setter"/>
+                                    <child>
+                                      <object class="GtkCellRendererText" id="renderer1"/>
+                                      <attributes>
+                                        <attribute name="text">0</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkHBox" id="hbox_schedule_monthly">
+                            <property name="visible">True</property>
+                            <child>
+                              <object class="GtkAlignment" id="alignment41">
+                                <property name="visible">True</property>
+                                <child>
+                                  <object class="GtkComboBox" id="monthly_combobox">
+                                    <property name="visible">True</property>
+                                    <property name="model">liststore2</property>
+                                    <property name="active">0</property>
+                                    <signal name="changed" handler="schedule_setter"/>
+                                    <child>
+                                      <object class="GtkCellRendererText" id="renderer2"/>
+                                      <attributes>
+                                        <attribute name="text">0</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">3</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkAlignment" id="alignment47">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="xscale">0</property>
+                            <property name="left_padding">5</property>
+                            <child>
+                              <object class="GtkLabel" id="monthly_text_label">
+                                <property name="visible">True</property>
+                                <property name="label" translatable="yes">day of the month</property>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">4</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkAlignment" id="alignment48">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="xscale">0</property>
+                    <property name="top_padding">10</property>
+                    <property name="left_padding">15</property>
+                    <child>
+                      <object class="GtkLabel" id="schedule_label_sent">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">label</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">8</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkVBox" id="vbox_managed_convert">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkAlignment" id="alignment43">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="xscale">0</property>
+                <child>
+                  <object class="GtkLabel" id="label30">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Select the server configuration file</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkAlignment" id="alignment44">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="xscale">0</property>
+                <property name="left_padding">25</property>
+                <child>
+                  <object class="GtkFileChooserButton" id="managedfilechooser">
+                    <property name="visible">True</property>
+                    <property name="width_chars">20</property>
+                    <signal name="selection_changed" handler="on_managedfilechooser_selection_changed"/>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkAlignment" id="alignment45">
+                <property name="visible">True</property>
+                <property name="xalign">0</property>
+                <property name="xscale">0</property>
+                <property name="top_padding">10</property>
+                <property name="bottom_padding">10</property>
+                <property name="left_padding">10</property>
+                <child>
+                  <object class="GtkLabel" id="managed_label_isfile">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Error: The file you selected is not a valid configuration file or is corrupt.</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">9</property>
+          </packing>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="padding">6</property>
+        <property name="position">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkAlignment" id="alignment19">
+        <property name="visible">True</property>
+        <property name="xalign">0</property>
+        <property name="yalign">1</property>
+        <property name="yscale">0</property>
+        <child>
           <object class="GtkHBox" id="button_box">
             <property name="visible">True</property>
             <child>
-              <object class="GtkAlignment" id="alignment19">
+              <object class="GtkAlignment" id="alignment20">
                 <property name="visible">True</property>
                 <child>
                   <object class="GtkButton" id="back_button">
@@ -692,7 +1193,7 @@
               </packing>
             </child>
             <child>
-              <object class="GtkAlignment" id="alignment20">
+              <object class="GtkAlignment" id="alignment49">
                 <property name="visible">True</property>
                 <child>
                   <object class="GtkButton" id="next_button">
@@ -709,16 +1210,268 @@
               </packing>
             </child>
           </object>
-          <packing>
-            <property name="position">8</property>
-          </packing>
         </child>
       </object>
       <packing>
         <property name="expand">False</property>
-        <property name="padding">6</property>
-        <property name="position">2</property>
+        <property name="fill">False</property>
+        <property name="pack_type">end</property>
+        <property name="position">3</property>
       </packing>
     </child>
   </object>
+  <object class="GtkListStore" id="liststore1">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Sunday</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Monday</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Tuesday</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Wednesday</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Thursday</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Friday</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Saturday</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkListStore" id="liststore2">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">1</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">2</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">3</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">4</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">5</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">6</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">7</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">8</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">9</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">10</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">11</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">12</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">13</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">14</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">15</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">16</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">17</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">18</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">19</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">20</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">21</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">22</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">23</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">24</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">25</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">26</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">27</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">28</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">29</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">30</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">31</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkListStore" id="liststore3">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">0</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">1</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">2</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">3</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">4</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">5</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">6</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">7</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">8</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">9</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">10</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">11</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">12</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">13</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">14</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">15</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">16</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">17</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">18</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">19</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">20</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">21</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">22</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">23</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkListStore" id="liststore4">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">00</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">05</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">10</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">15</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">20</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">25</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">30</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">35</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">40</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">45</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">50</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">55</col>
+      </row>
+    </data>
+  </object>
 </interface>