mythbuntu-dev team mailing list archive
-
mythbuntu-dev team
-
Mailing list archive
-
Message #00039
[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>