1
# -*- coding: utf-8 -*-
3
# Copyright (C) 2010 Canonical Ltd.
6
# Andres Rodriguez <andreserl@ubuntu.com>
8
# This program is free software: you can redistribute it and/or modify it
9
# under the terms of the GNU General Public License version 3, as published
10
# by the Free Software Foundation.
12
# This program is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranties of
14
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15
# PURPOSE. See the GNU General Public License for more details.
17
# You should have received a copy of the GNU General Public License along
18
# with this program. If not, see <http://www.gnu.org/licenses/>.
21
#from desktopcouch.records.server import CouchDatabase
22
#from desktopcouch.records.record import Record
27
from testdrive import testdrive
29
from testdrivegtk.helpers import get_builder
32
from gettext import gettext as _
33
gettext.textdomain('testdrive')
35
ISO_REPOSITORY = ['cdimage', 'releases']
36
MEM_SIZE_TAB = ['256', '384', '512', _('Other...')]
37
DISK_SIZE_TAB = ['4', '6', '8', _('Other...')]
39
class PreferencesTestdrivegtkDialog(gtk.Dialog):
40
__gtype_name__ = "PreferencesTestdrivegtkDialog"
44
"""Special static method that's automatically called by Python when
45
constructing a new instance of this class.
47
Returns a fully instantiated PreferencesTestdrivegtkDialog object.
50
logging.basicConfig(level=logging.DEBUG)
51
logger1 = logging.getLogger('gtkpreferences')
52
logger1.debug('__new__')
54
builder = get_builder('PreferencesTestdrivegtkDialog')
55
new_object = builder.get_object("preferences_testdrivegtk_dialog")
56
new_object.finish_initializing(builder, logger1)
59
def finish_initializing(self, builder, logger1):
60
"""Called while initializing this instance in __new__
62
finish_initalizing should be called after parsing the ui definition
63
and creating a PreferencesTestdrivegtkDialog object with it in order to
64
finish initializing the start of the new PerferencesTestdrivegtkDialog
67
Put your initialization code in here and leave __init__ undefined.
69
# Get a reference to the builder and set up the signals.
70
self.builder = builder
71
self.builder.connect_signals(self)
72
self.set_title(_("TestDrive Preferences"))
75
##################################################################
76
###### Starting code of instancing TestDrive in Prefereces #######
77
##################################################################
78
# Instancing a testdrive object.
79
self.td = testdrive.Testdrive('testdrive-gtk')
81
# Initializing local variables, loading config files, setting defaults.
82
self.initialize_variables()
83
self.initialize_config_files()
84
self.td.set_defaults()
86
# Grab the selected repo and store it temporarly.
87
# Then, use the hardcoded repos to update the cache.
88
# Finally, default the initially selected repo.
89
selected_repo = self.td.p
90
for repo in ISO_REPOSITORY:
92
self.update_iso_cache()
93
self.td.p = selected_repo
95
# Initialize widgets and its values
96
self.initialize_widgets()
97
self.initialize_widgets_values()
98
self.logger.debug(_('finish_initialization()'))
100
def initialize_variables(self):
101
self.virt_method = None
103
self.disk_size = None
109
def initialize_widgets(self):
110
##################################################################
111
########### Initializing all the widgets in variables ############
112
##################################################################
113
# Initialize Data Paths
114
self.txt_gral_cache = self.builder.get_object("txt_gral_cache")
115
self.txt_img_cache = self.builder.get_object("txt_img_cache")
116
self.txt_iso_cache = self.builder.get_object("txt_iso_cache")
117
self.txt_iso_list_cache = self.builder.get_object("txt_iso_list_cache")
119
self.btn_iso_clean = self.builder.get_object("btn_iso_clean")
120
self.btn_iso_clean.connect("clicked", self.on_cache_cleanup_clicked, self.td.CACHE_ISO)
121
self.btn_img_clean = self.builder.get_object("btn_img_clean")
122
self.btn_img_clean.connect("clicked", self.on_cache_cleanup_clicked, self.td.CACHE_IMG)
123
self.btn_update_iso_list_cache = self.builder.get_object("btn_update_iso_list_cache")
124
self.btn_update_iso_list_cache.connect("clicked", self.on_force_iso_list_update)
127
self.chk_arch_i386 = self.builder.get_object("chk_arch_i386")
128
self.chk_arch_i386.connect("clicked", self.on_select_arch, "i386")
129
self.chk_arch_amd64 = self.builder.get_object("chk_arch_amd64")
130
self.chk_arch_amd64.connect("clicked", self.on_select_arch, "amd64")
132
# Ubuntu Repositories Combo Box
133
self.tb_ubuntu_release_prefs = self.builder.get_object("tb_ubuntu_release_prefs")
134
self.cb_ubuntu_repo = gtk.combo_box_new_text()
135
self.cb_ubuntu_repo.set_size_request(260, -1)
136
self.cb_ubuntu_repo.append_text(_('Select Repository:'))
137
for repo in ISO_REPOSITORY:
138
self.cb_ubuntu_repo.append_text(repo)
139
self.cb_ubuntu_repo.connect('changed', self.on_select_iso_image_repo)
140
self.cb_ubuntu_repo.set_active(0)
141
self.cb_ubuntu_repo.show()
142
self.tb_ubuntu_release_prefs.attach(self.cb_ubuntu_repo, 1,2,0,1, gtk.FILL)
143
# Ubuntu Releases Combo Box
144
self.cb_ubuntu_release = gtk.combo_box_new_text()
145
self.cb_ubuntu_release.set_size_request(260, -1)
146
self.cb_ubuntu_release.connect('changed', self.on_select_ubuntu_release)
147
self.cb_ubuntu_release.append_text(_('Select Release:'))
148
self.cb_ubuntu_release.set_active(0)
149
self.cb_ubuntu_release.show()
150
self.tb_ubuntu_release_prefs.attach(self.cb_ubuntu_release, 1,2,1,2, gtk.FILL)
152
# Initialize Virtualization Method Options
153
self.opt_virt_kvm = self.builder.get_object("opt_virt_kvm")
154
self.opt_virt_kvm.connect("toggled", self.on_select_virt_method, "kvm")
155
self.opt_virt_vbox = self.builder.get_object("opt_virt_vbox")
156
self.opt_virt_vbox.connect("toggled", self.on_select_virt_method, "virtualbox")
157
self.opt_virt_parallels = self.builder.get_object("opt_virt_parallels")
158
self.opt_virt_parallels.connect("toggled", self.on_select_virt_method, "parallels")
160
# Initialize Memory Options
161
self.cbe_mem_size = self.builder.get_object("cbe_mem_size")
162
self.cbe_mem_size.remove_text(0)
163
for mem in MEM_SIZE_TAB:
164
self.cbe_mem_size.append_text(mem)
165
self.cbe_mem_size.connect('changed', self.on_select_mem)
167
# Initialize Disk Size Options
168
self.cbe_disk_size = self.builder.get_object("cbe_disk_size")
169
self.cbe_disk_size.remove_text(0)
170
for disk in DISK_SIZE_TAB:
171
self.cbe_disk_size.append_text(disk)
172
self.cbe_disk_size.connect('changed', self.on_select_disk_size)
175
self.txt_kvm_args = self.builder.get_object("txt_kvm_args")
176
self.lb_kvm_args = self.builder.get_object("lb_kvm_args")
179
self.lb_smp_nbr = self.builder.get_object("lb_smp_nbr")
180
self.txt_smp_nbr = self.builder.get_object("txt_smp_nbr")
181
self.lb_smp_available = self.builder.get_object("lb_smp_available")
184
self.chk_flavor_ubuntu = self.builder.get_object("chk_flavor_ubuntu")
185
self.chk_flavor_ubuntu.connect("clicked", self.on_select_flavors)
186
self.chk_flavor_kubuntu = self.builder.get_object("chk_flavor_kubuntu")
187
self.chk_flavor_kubuntu.connect("clicked", self.on_select_flavors)
188
self.chk_flavor_xubuntu = self.builder.get_object("chk_flavor_xubuntu")
189
self.chk_flavor_xubuntu.connect("clicked", self.on_select_flavors)
190
self.chk_flavor_edubuntu = self.builder.get_object("chk_flavor_edubuntu")
191
self.chk_flavor_edubuntu.connect("clicked", self.on_select_flavors)
192
self.chk_flavor_mythbuntu = self.builder.get_object("chk_flavor_mythbuntu")
193
self.chk_flavor_mythbuntu.connect("clicked", self.on_select_flavors)
194
self.chk_flavor_ubuntustudio = self.builder.get_object("chk_flavor_ubuntustudio")
195
self.chk_flavor_ubuntustudio.connect("clicked", self.on_select_flavors)
196
self.chk_flavor_other = self.builder.get_object("chk_flavor_other")
197
self.chk_flavor_other.connect("clicked", self.on_select_flavors)
199
def initialize_config_files(self):
200
##################################################################
201
########### Read the configuration file for settings #############
202
##################################################################
203
config_files = ["/etc/%s" % self.td.PKGRC, "%s/.%s" % (self.td.HOME, self.td.PKGRC), "%s/.config/%s/%s" % (self.td.HOME, self.td.PKG, self.td.PKGRC) ]
204
for file in config_files:
205
if os.path.exists(file):
207
# Load config files for class
208
self.td.load_config_file(file)
209
# Load config files for local variables
210
#self.load_config_files(file)
211
self.logger.debug(_("Reading config file: [%s]") % file)
213
self.logger.debug(_("Unable to load config file [%s]") % file)
217
def initialize_widgets_values(self):
218
##################################################################
219
###### Initialize the widget values - Displayes information ######
220
##################################################################
222
self.txt_gral_cache.set_text(self.td.CACHE)
223
self.txt_img_cache.set_text(self.td.CACHE_IMG)
224
self.txt_iso_cache.set_text(self.td.CACHE_ISO)
226
# Determine the selected repository
227
if self.td.p == 'cdimage':
228
self.cb_ubuntu_repo.set_active(1)
229
elif self.td.p == 'releases':
230
self.cb_ubuntu_repo.set_active(2)
233
if self.td.VIRT == 'kvm':
234
self.opt_virt_kvm.set_active(True)
235
elif self.td.VIRT == 'virtualbox':
236
self.opt_virt_vbox.set_active(True)
237
elif self.td.VIRT == 'parallels':
238
self.opt_virt_parallels.set_active(True)
241
if self.td.MEM == '256':
242
self.cbe_mem_size.set_active(0)
243
elif self.td.MEM == '384':
244
self.cbe_mem_size.set_active(1)
245
elif self.td.MEM == '512':
246
self.cbe_mem_size.set_active(2)
248
self.cbe_mem_size.append_text(self.td.MEM)
249
self.cbe_mem_size.set_active(4)
252
if self.td.DISK_SIZE == '4G':
253
self.cbe_disk_size.set_active(0)
254
elif self.td.DISK_SIZE == '6G':
255
self.cbe_disk_size.set_active(1)
256
elif self.td.DISK_SIZE == '8G':
257
self.cbe_disk_size.set_active(2)
259
self.cbe_disk_size.append_text(self.td.DISK_SIZE.replace('G', ''))
260
self.cbe_disk_size.set_active(4)
263
self.txt_kvm_args.set_text(self.td.KVM_ARGS)
267
self.txt_smp_nbr.set_text(self.td.SMP)
268
self.lb_smp_available.set_text(_(" of %s available.") % commands.getoutput("grep -c ^processor /proc/cpuinfo"))
274
flavor = self.td.f.split()[i].replace(',', '')
275
if flavor == 'ubuntu':
276
self.chk_flavor_ubuntu.set_active(True)
277
elif flavor == 'kubuntu':
278
self.chk_flavor_kubuntu.set_active(True)
279
elif flavor == 'xubuntu':
280
self.chk_flavor_xubuntu.set_active(True)
281
elif flavor == 'edubuntu':
282
self.chk_flavor_edubuntu.set_active(True)
283
elif flavor == 'mythbuntu':
284
self.chk_flavor_mythbuntu.set_active(True)
285
elif flavor == 'ubuntustudio':
286
self.chk_flavor_ubuntustudio.set_active(True)
287
elif flavor == 'other':
288
self.chk_flavor_other.set_active(True)
297
for arch in self.td.m:
299
self.chk_arch_i386.set_active(True)
301
self.chk_arch_amd64.set_active(True)
303
def update_iso_cache(self, force_update = False):
304
##################################################################
305
###### Code to update the ISO list from the repository Cache #####
306
##################################################################
309
""" Verify if the ISO list is cached, if not, set variable to update/create it. """
310
if force_update is True:
313
elif self.td.is_iso_list_cached() is False:
315
# If ISO list is cached, verify if it is expired. If it is, set variable to update it.
316
elif self.td.is_iso_list_cache_expired() is True:
319
""" If variable set to update, obtain the ISO list from the Ubuntu CD Image repository. """
320
if update_cache == 1:
321
self.logger.info(_("Obtaining Ubuntu ISO list from %s...") % self.td.u)
323
cdimage = self.td.obtain_ubuntu_iso_list_from_repo()
325
self.logger.error(_("Could not obtain the Ubuntu ISO list from %s...") % self.td.u)
327
""" If the ISO List was obtained, update the cache file"""
329
self.logger.info(_("Updating the Ubuntu ISO list cache..."))
331
self.td.update_ubuntu_iso_list_cache(cdimage)
333
self.logger.error(_("Unable to update the Ubuntu ISO list cache..."))
335
def get_preferences(self):
336
"""Returns preferences for testdrivegtk."""
337
self.logger.debug(_("get_preferences()"))
340
def _load_preferences(self):
341
# TODO: add preferences to the self._preferences dict default
342
# preferences that will be overwritten if some are saved
345
def _save_preferences(self):
346
##################################################################
347
########### Saving the preferences to the config file ############
348
##################################################################
350
config = ConfigParser.RawConfigParser()
351
config.add_section(self.td.PKG_SECTION)
352
for prefs in self.preferences:
353
config.set(self.td.PKG_SECTION, prefs[0], prefs[1])
354
# Writing our configuration file
355
path = "%s/.%s" % (self.td.HOME, self.td.PKGRC)
356
with open(path, 'wb') as configfile:
357
config.write(configfile)
359
def ok(self, widget, data=None):
360
"""The user has elected to save the changes.
362
Called before the dialog returns gtk.RESONSE_OK from run().
365
# Make any updates to self._preferences here. e.g.
366
self.update_preferences()
367
self._save_preferences()
369
def cancel(self, widget, data=None):
370
"""The user has elected cancel changes.
372
Called before the dialog returns gtk.RESPONSE_CANCEL for run()
374
# Restore any changes to self._preferences here.
377
def on_error_dlg(self, data=None):
378
errorbox = gtk.MessageDialog(self,
379
gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR,
380
gtk.BUTTONS_CLOSE, data)
381
response = errorbox.run()
384
def on_select_virt_method(self, widget, virt=None):
385
# On selecting the viratualization method
386
self.virt_method = virt
387
# If Virtualization method is KVM, display related options.
389
self.txt_kvm_args.set_sensitive(True)
390
self.txt_smp_nbr.set_sensitive(True)
392
self.txt_kvm_args.set_sensitive(False)
393
self.txt_smp_nbr.set_sensitive(False)
395
def on_select_mem(self, entry):
396
# On selecting RAM memory.
397
if entry.child.get_text() == MEM_SIZE_TAB[3]:
398
entry.child.set_editable(True)
400
elif entry.get_active() >= 0:
401
entry.child.set_editable(False)
402
self.mem = entry.child.get_text()
404
def on_select_disk_size(self, entry):
405
# On selecting disk size
406
if entry.child.get_text() == DISK_SIZE_TAB[3]:
407
entry.child.set_editable(True)
408
self.disk_size = 'other'
409
elif entry.get_active() >= 0:
410
entry.child.set_editable(False)
411
self.disk_size = entry.child.get_text()
413
def on_select_flavors(self, widget):
414
# On selecting Ubuntu Flavors
416
if self.chk_flavor_ubuntu.get_active():
417
self.flavors = self.flavors + "ubuntu, "
418
if self.chk_flavor_kubuntu.get_active():
419
self.flavors = self.flavors + "kubuntu, "
420
if self.chk_flavor_xubuntu.get_active():
421
self.flavors = self.flavors + "xubuntu, "
422
if self.chk_flavor_edubuntu.get_active():
423
self.flavors = self.flavors + "edubuntu, "
424
if self.chk_flavor_mythbuntu.get_active():
425
self.flavors = self.flavors + "mythbuntu, "
426
if self.chk_flavor_ubuntustudio.get_active():
427
self.flavors = self.flavors + "ubuntustudio, "
428
if self.chk_flavor_other.get_active():
429
self.flavors = self.flavors + "other, "
431
def on_select_arch(self, widget, arch):
432
# On selecting the architecture
433
if widget.get_active() == True:
434
self.arch.append(arch)
435
if widget.get_active() == False:
436
self.arch.remove(arch)
438
def on_txt_gral_cache_focus_out_event(self, widget, data=None):
439
# When the CACHE text is changed, update related cache paths.
440
txt_cache = self.txt_gral_cache.get_text()
441
self.txt_iso_cache.set_text("%s/iso" % txt_cache)
442
self.txt_img_cache.set_text("%s/img" % txt_cache)
444
def on_cache_cleanup_clicked(self, widget, cache_path):
445
# Method to cleanup cache
446
filelist = os.listdir(cache_path)
452
for file in filelist:
453
path = "%s/%s" % (cache_path, file)
456
on_error_dlg(_("Unable to clean up files from [%s]") % cache_path)
458
def on_select_iso_image_repo(self, widget):
459
##################################################################
460
#### Select image repo, populate Release combobox accordingly ####
461
##################################################################
462
model = widget.get_model()
463
index = widget.get_active()
466
self.repo = model[index][0]
467
self.td.p = self.repo
468
self.txt_iso_list_cache.set_text("%s/%s.isos" % (self.td.CACHE, self.td.p))
470
# Update cache commented given the hack to sync every repo on initialization
471
#self.update_iso_cache()
472
# Populate the releases combobox
473
self.cb_ubuntu_release.get_model().clear()
474
self.cb_ubuntu_release.append_text(_('Select Release:'))
475
self.cb_ubuntu_release.set_active(0)
476
isos = self.td.get_ubuntu_iso_list()
479
codenames.append(iso.split()[1])
480
codenames = list(set(codenames))
484
for release in codenames:
485
self.cb_ubuntu_release.append_text(release)
487
if release == self.td.r and self.td.p == old_repo:
489
if self.td.r is None:
490
self.cb_ubuntu_release.set_active(1)
492
self.cb_ubuntu_release.set_active(i)
496
def on_select_ubuntu_release(self, widget):
497
model = widget.get_model()
498
index = widget.get_active()
500
self.r = model[index][0]
504
def on_force_iso_list_update(self, widget):
505
selected_repo = self.td.p
506
for repo in ISO_REPOSITORY:
508
self.update_iso_cache(True)
509
self.td.p = selected_repo
511
def update_preferences(self):
512
##################################################################
513
###### Prepare the preferences to be saved in the config fiel ####
514
##################################################################
515
self.preferences = []
517
if self.td.CACHE != self.txt_gral_cache.get_text():
518
self.td.CACHE = self.txt_gral_cache.get_text()
519
self.preferences.append(['cache', self.td.CACHE])
520
if self.td.CACHE_IMG != self.txt_img_cache.get_text():
521
self.td.CACHE_IMG = self.txt_img_cache.get_text()
522
self.preferences.append(['cache_img', self.td.CACHE_IMG])
523
if self.td.CACHE_ISO != self.txt_iso_cache.get_text():
524
self.td.CACHE_ISO = self.txt_iso_cache.get_text()
525
self.preferences.append(['cache_iso', self.td.CACHE_ISO])
528
if self.repo != None:
529
self.preferences.append(['p', self.td.p])
531
if self.td.r != self.r:
534
self.preferences.append(['r', self.td.r])
537
if self.td.KVM_ARGS != self.txt_kvm_args.get_text():
538
self.td.KVM_ARGS = self.txt_kvm_args.get_text()
539
self.preferences.append(['kvm_args', self.td.KVM_ARGS])
541
if self.td.SMP != self.txt_smp_nbr.get_text():
542
self.td.SMP = self.txt_smp_nbr.get_text()
543
self.preferences.append(['smp', self.td.SMP])
546
if 'amd64' in self.arch and 'i386' in self.arch:
547
self.td.m = self.arch
549
elif 'amd64' in self.arch or 'i386' in self.arch:
550
self.td.m = self.arch
551
self.preferences.append(['m', self.td.m[0]])
554
if self.td.VIRT != self.virt_method and self.virt_method != None:
555
self.td.VIRT = self.virt_method
556
self.preferences.append(['virt', self.td.VIRT])
558
# Memory - TODO: Add validation of text
559
if self.mem == 'other':
560
self.mem = self.cbe_mem_size.child.get_text()
561
if self.td.MEM != self.mem or self.mem not in MEM_SIZE_TAB:
562
self.td.MEM = self.mem
563
self.preferences.append(['mem', self.td.MEM])
565
# Disk Size - TODO: Add validation of text
566
if self.disk_size == 'other':
567
self.disk_size = self.cbe_disk_size.child.get_text()
568
if self.td.DISK_SIZE.replace('G','') != self.disk_size or self.disk_size not in DISK_SIZE_TAB:
569
self.td.DISK_SIZE = "%sG" % self.disk_size
570
self.preferences.append(['disk_size', self.td.DISK_SIZE])
573
#if self.td.f != self.flavors[:-2]:
574
self.td.f = self.flavors[:-2]
575
self.preferences.append(['f', self.td.f])
577
if __name__ == "__main__":
578
dialog = PreferencesTestdrivegtkDialog()