+ def load_settings(self):
+ default_settings = {
+ 'tbl_version': self.tbl_version,
+ 'preferred': 'stable',
+ 'installed_version': {
+ 'stable': False,
+ 'alpha': False
+ },
+ 'latest_version': {
+ 'stable': '0',
+ 'alpha': '0'
+ },
+ 'update_over_tor': True,
+ 'check_for_updates': False,
+ 'last_update_check_timestamp': 0
+ }
+
+ if os.path.isfile(self.paths['settings_file']):
+ settings = pickle.load(open(self.paths['settings_file']))
+
+ # what version settings is this?
+ if not 'tbl_version' in settings:
+ settings['tbl_version'] = '0.0.1'
+
+ # sanity checks for current version
+ if settings['tbl_version'] == self.tbl_version:
+ good_settings = True
+ if not 'preferred' in settings:
+ good_settings = False
+ if not 'installed_version' in settings:
+ good_settings = False
+ if not 'stable' in settings['installed_version']:
+ good_settings = False
+ if not 'alpha' in settings['installed_version']:
+ good_settings = False
+ if not 'latest_version' in settings:
+ good_settings = False
+ if not 'stable' in settings['latest_version']:
+ good_settings = False
+ if not 'alpha' in settings['latest_version']:
+ good_settings = False
+ if not 'update_over_tor' in settings:
+ good_settings = False
+ if not 'check_for_updates' in settings:
+ good_settings = False
+ if not 'last_update_check_timestamp' in settings:
+ good_settings = False
+
+ if good_settings:
+ self.settings = settings
+ else:
+ self.settings = default_settings
+
+ # settings migrations for previous versions
+ elif settings['tbl_version'] == '0.0.1':
+ self.settings = default_settings
+ self.settings['installed_version']['alpha'] = settings['installed_version']
+ self.save_settings()
+
+ # move tbb alpha
+ self.mkdir(self.paths['tbb']['alpha']['dir'])
+ # todo: move already-installed TBB alpha to new location
+ if os.path.exists(self.paths['data_dir']+'/tbb/x86_64'):
+ pass
+ if os.path.exists(self.paths['data_dir']+'/tbb/i686'):
+ pass
+
+ else:
+ self.settings = default_settings
+ self.save_settings()
+
+ # save settings
+ def save_settings(self):
+ pickle.dump(self.settings, open(self.paths['settings_file'], 'w'))
+ return True
+
+ # get the process id of a program
+ def get_pid(self, bin_path, python = False):
+ pid = None
+
+ for p in psutil.process_iter():
+ try:
+ if p.pid != os.getpid():
+ exe = None
+ if python:
+ if len(p.cmdline) > 1:
+ if 'python' in p.cmdline[0]:
+ exe = p.cmdline[1]
+ else:
+ if len(p.cmdline) > 0:
+ exe = p.cmdline[0]
+
+ if exe == bin_path:
+ pid = p.pid
+
+ except:
+ pass
+
+ return pid
+
+ # bring program's x window to front
+ def bring_window_to_front(self, pid):
+ # figure out the window id
+ win_id = None
+ p = subprocess.Popen(['wmctrl', '-l', '-p'], stdout=subprocess.PIPE)
+ for line in p.stdout.readlines():
+ line_split = line.split()
+ cur_win_id = line_split[0]
+ cur_win_pid = int(line_split[2])
+ if cur_win_pid == pid:
+ win_id = cur_win_id
+
+ # bring to front
+ if win_id:
+ subprocess.call(['wmctrl', '-i', '-a', win_id])
+
+class TBLSettings:
+ def __init__(self, common):
+ print _('Starting settings dialog')
+ self.common = common
+
+ # set up the window
+ self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+ self.window.set_title(_("Tor Browser Launcher Settings"))
+ self.window.set_icon_from_file(self.common.paths['icon_file'])
+ self.window.set_position(gtk.WIN_POS_CENTER)
+ self.window.set_border_width(10)
+ self.window.connect("delete_event", self.delete_event)
+ self.window.connect("destroy", self.destroy)
+
+ # build the rest of the UI
+ self.box = gtk.VBox(False, 10)
+ self.window.add(self.box)
+ self.box.show()
+
+ self.hbox = gtk.HBox(False, 10)
+ self.box.pack_start(self.hbox, True, True, 0)
+ self.hbox.show()
+
+ self.settings_box = gtk.VBox(False, 10)
+ self.hbox.pack_start(self.settings_box, True, True, 0)
+ self.settings_box.show()
+
+ self.labels_box = gtk.VBox(False, 10)
+ self.hbox.pack_start(self.labels_box, True, True, 0)
+ self.labels_box.show()
+
+ # preferred version
+ self.preferred_box = gtk.HBox(False, 10)
+ self.settings_box.pack_start(self.preferred_box, True, True, 0)
+ self.preferred_box.show()
+
+ self.preferred_label = gtk.Label(_('I prefer'))
+ self.preferred_label.set_line_wrap(True)
+ self.preferred_box.pack_start(self.preferred_label, True, True, 0)
+ self.preferred_label.show()
+
+ self.preferred_options = []
+ for i in self.common.available_versions:
+ self.preferred_options.append(self.common.available_versions[i])
+ self.preferred_options.sort()
+
+ self.preferred = gtk.combo_box_new_text()
+ for option in self.preferred_options:
+ self.preferred.append_text(option)
+ if self.common.settings['preferred'] in self.common.available_versions:
+ self.preferred.set_active( self.preferred_options.index(self.common.available_versions[self.common.settings['preferred']]) )
+ else:
+ self.preferred.set_active(0)
+ self.preferred_box.pack_start(self.preferred, True, True, 0)
+ self.preferred.show()
+
+ # download over tor
+ self.tor_update_checkbox = gtk.CheckButton(_("Download updates over Tor (recommended)"))
+ self.settings_box.pack_start(self.tor_update_checkbox, True, True, 0)
+ if self.common.settings['update_over_tor']:
+ self.tor_update_checkbox.set_active(True)
+ else:
+ self.tor_update_checkbox.set_active(False)
+ self.tor_update_checkbox.show()
+
+ # check for updates
+ self.update_checkbox = gtk.CheckButton(_("Check for updates next launch"))
+ self.settings_box.pack_start(self.update_checkbox, True, True, 0)
+ if self.common.settings['check_for_updates']:
+ self.update_checkbox.set_active(True)
+ else:
+ self.update_checkbox.set_active(False)
+ self.update_checkbox.show()
+
+ # labels
+ if(self.common.settings['installed_version'][self.common.settings['preferred']]):
+ self.label1 = gtk.Label(_('Installed version:\n{0}').format(self.common.settings['installed_version'][self.common.settings['preferred']]))
+ else:
+ self.label1 = gtk.Label(_('Not installed'))
+ self.label1.set_line_wrap(True)
+ self.labels_box.pack_start(self.label1, True, True, 0)
+ self.label1.show()
+
+ if(self.common.settings['last_update_check_timestamp'] > 0):
+ self.label1 = gtk.Label(_('Last checked for updates:\n{0}').format(time.strftime("%B %d, %Y %I:%M %P", time.gmtime(self.common.settings['last_update_check_timestamp']))))
+ else:
+ self.label1 = gtk.Label(_('Never checked for updates'))
+ self.label1.set_line_wrap(True)
+ self.labels_box.pack_start(self.label1, True, True, 0)
+ self.label1.show()
+
+ # button box
+ self.button_box = gtk.HButtonBox()
+ self.button_box.set_layout(gtk.BUTTONBOX_SPREAD)
+ self.box.pack_start(self.button_box, True, True, 0)
+ self.button_box.show()
+
+ # save and launch button
+ save_launch_image = gtk.Image()
+ save_launch_image.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_BUTTON)
+ self.save_launch_button = gtk.Button(_("Launch Tor Browser"))
+ self.save_launch_button.set_image(save_launch_image)
+ self.save_launch_button.connect("clicked", self.save_launch, None)
+ self.button_box.add(self.save_launch_button)
+ self.save_launch_button.show()
+
+ # save and exit button
+ save_exit_image = gtk.Image()
+ save_exit_image.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_BUTTON)
+ self.save_exit_button = gtk.Button(_("Save & Exit"))
+ self.save_exit_button.set_image(save_exit_image)
+ self.save_exit_button.connect("clicked", self.save_exit, None)
+ self.button_box.add(self.save_exit_button)
+ self.save_exit_button.show()
+
+ # cancel button
+ cancel_image = gtk.Image()
+ cancel_image.set_from_stock(gtk.STOCK_CANCEL, gtk.ICON_SIZE_BUTTON)
+ self.cancel_button = gtk.Button(_("Cancel"))
+ self.cancel_button.set_image(cancel_image)
+ self.cancel_button.connect("clicked", self.destroy, None)
+ self.button_box.add(self.cancel_button)
+ self.cancel_button.show()
+
+ # show the window
+ self.window.show()
+
+ # start gtk
+ gtk.main()
+
+ # save and launch
+ def save_launch(self, widget, data=None):
+ self.save()
+ p = subprocess.Popen([self.common.paths['tbl_bin']])
+ self.destroy(False)
+
+ # save and exit
+ def save_exit(self, widget, data=None):
+ self.save()
+ self.destroy(False)
+
+ # save settings
+ def save(self):
+ # figure out the selected preferred option
+ preferred = None
+ selected = self.preferred_options[self.preferred.get_active()]
+ for i in self.common.available_versions:
+ if self.common.available_versions[i] == selected:
+ preferred = i
+ if preferred:
+ self.common.settings['preferred'] = preferred
+
+ # checkbox options
+ self.common.settings['update_over_tor'] = self.tor_update_checkbox.get_active()
+ self.common.settings['check_for_updates'] = self.update_checkbox.get_active()
+
+ # save them
+ self.common.save_settings()
+
+ # exit
+ def delete_event(self, widget, event, data=None):
+ return False
+ def destroy(self, widget, data=None):
+ gtk.main_quit()
+
+
+class TBLLauncher:
+ def __init__(self, common):
+ print _('Starting launcher dialog')
+ self.common = common
+
+ # init launcher
+ self.set_gui(None, '', [])
+ self.launch_gui = True
+ self.common.build_paths(self.common.settings['latest_version'][self.common.settings['preferred']])
+
+ # is vidalia already running and we just need to open a new firefox?
+ if self.common.settings['installed_version']:
+ vidalia_pid = self.common.get_pid('./App/vidalia')
+ firefox_pid = self.common.get_pid(self.common.paths['tbb'][self.common.settings['preferred']]['firefox_bin'])
+
+ if vidalia_pid and not firefox_pid:
+ print _('Vidalia is already open, but Firefox is closed. Launching new Firefox.')
+ self.common.bring_window_to_front(vidalia_pid)
+ subprocess.Popen([self.common.paths['tbb'][self.common.settings['preferred']]['firefox_bin'], '-no-remote', '-profile', self.common.paths['tbb'][self.common.settings['preferred']]['firefox_profile']])
+ return
+ elif vidalia_pid and firefox_pid:
+ print _('Vidalia and Firefox are already open, bringing them to focus')
+
+ # bring firefox to front, then vidalia
+ self.common.bring_window_to_front(firefox_pid)
+ self.common.bring_window_to_front(vidalia_pid)
+ return
+
+ # check for updates?
+ check_for_updates = False
+ if self.common.settings['check_for_updates']:
+ check_for_updates = True
+
+ if not check_for_updates:
+ # how long was it since the last update check?
+ # 86400 seconds = 24 hours
+ current_timestamp = int(time.time())
+ if current_timestamp - self.common.settings['last_update_check_timestamp'] >= 86400:
+ check_for_updates = True
+
+ if check_for_updates:
+ # check for update
+ print 'Checking for update'
+ self.set_gui('task', _("Checking for Tor Browser update."),
+ ['download_update_check',
+ 'attempt_update'])
+ else:
+ # no need to check for update
+ print _('Checked for update within 24 hours, skipping')
+ self.start_launcher()
+
+ if self.launch_gui:
+ # set up the window
+ self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+ self.window.set_title(_("Tor Browser"))
+ self.window.set_icon_from_file(self.common.paths['icon_file'])
+ self.window.set_position(gtk.WIN_POS_CENTER)
+ self.window.set_border_width(10)
+ self.window.connect("delete_event", self.delete_event)
+ self.window.connect("destroy", self.destroy)
+
+ # build the rest of the UI
+ self.build_ui()
+
+ # download or run TBB
+ def start_launcher(self):
+ # is TBB already installed?
+ start = self.common.paths['tbb'][self.common.settings['preferred']]['start']
+ if os.path.isfile(start) and os.access(start, os.X_OK):
+ if self.common.settings['installed_version'][self.common.settings['preferred']] == self.common.settings['latest_version'][self.common.settings['preferred']]:
+ # current version of tbb is installed, launch it
+ self.run(False)
+ self.launch_gui = False
+ elif self.common.settings['installed_version'][self.common.settings['preferred']] < self.common.settings['latest_version'][self.common.settings['preferred']]:
+ # there is a tbb upgrade available
+ self.set_gui('task', _("Your Tor Browser is out of date."),
+ ['download_tarball_sig',
+ 'download_tarball',
+ 'verify',
+ 'extract',
+ 'run'])
+ else:
+ # for some reason the installed tbb is newer than the current version?
+ self.set_gui('error', _("Something is wrong. The version of Tor Browser Bundle you have installed is newer than the current version?"), [])
+
+ # not installed