Tor Browser Launcher
https://github.com/micahflee/torbrowser-launcher/
-Copyright (c) 2013-2014 Micah Lee <micah@micahflee.com>
+Copyright (c) 2013-2017 Micah Lee <micah@micahflee.com>
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
OTHER DEALINGS IN THE SOFTWARE.
"""
-import subprocess, time
+import subprocess
+import shutil
-import pygtk
-pygtk.require('2.0')
-import gtk
+from PyQt5 import QtCore, QtWidgets, QtGui
+
+
+class Settings(QtWidgets.QMainWindow):
+ """
+ Settings window.
+ """
+ def __init__(self, common, app):
+ super(Settings, self).__init__()
-class Settings:
- def __init__(self, common):
- print _('Starting settings dialog')
self.common = common
+ self.app = app
+
+ # Set up the window
+ self.setWindowTitle(_("Tor Browser Launcher Settings"))
+ self.setWindowIcon(QtGui.QIcon(self.common.paths['icon_file']))
- # 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()
-
- # download over tor
- try:
- import txsocksx
- self.txsocks_found = True
- except ImportError:
- self.txsocks_found = False
- self.tor_update_checkbox = gtk.CheckButton(_("Download updates over Tor (recommended)"))
- if self.txsocks_found:
- self.tor_update_checkbox.set_tooltip_text(_("This option is only available when using a system wide Tor installation."))
+ # Download over system tor
+ self.tor_download_checkbox = QtWidgets.QCheckBox(_("Download over system Tor"))
+ if self.common.settings['download_over_tor']:
+ self.tor_download_checkbox.setCheckState(QtCore.Qt.Checked)
else:
- self.tor_update_checkbox.set_tooltip_text(_("This option requires the python-txsocksx package."))
+ self.tor_download_checkbox.setCheckState(QtCore.Qt.Unchecked)
- self.settings_box.pack_start(self.tor_update_checkbox, True, True, 0)
- if self.common.settings['update_over_tor'] and self.txsocks_found:
- self.tor_update_checkbox.set_active(True)
+ # Force en-US, only display if language isn't already en-US
+ self.force_en_checkbox = QtWidgets.QCheckBox(_("Force downloading English version of Tor Browser"))
+ if self.common.settings['force_en-US']:
+ self.force_en_checkbox.setCheckState(QtCore.Qt.Checked)
else:
- self.tor_update_checkbox.set_active(False)
+ self.force_en_checkbox.setCheckState(QtCore.Qt.Unchecked)
+ if self.common.language == 'en-US':
+ self.force_en_checkbox.hide()
+
+ # Tor SOCKS address
+ tor_addr_label = QtWidgets.QLabel(_('Tor server'))
+ self.tor_addr = QtWidgets.QLineEdit()
+ self.tor_addr.setText(self.common.settings['tor_socks_address'])
+ tor_addr_layout = QtWidgets.QHBoxLayout()
+ tor_addr_layout.addWidget(tor_addr_label)
+ tor_addr_layout.addWidget(self.tor_addr)
+
+ # Settings layout
+ settings_layout = QtWidgets.QVBoxLayout()
+ settings_layout.addWidget(self.tor_download_checkbox)
+ settings_layout.addWidget(self.force_en_checkbox)
+ settings_layout.addLayout(tor_addr_layout)
+
+ # Status
+ status_label = QtWidgets.QLabel()
+ if(self.common.settings['installed']):
+ status_label.setText(_('Status: Installed'))
+ else:
+ status_label.setText(_('Status: Not Installed'))
- if self.txsocks_found == False:
- self.tor_update_checkbox.set_sensitive(False)
+ # Install button
+ install_button = QtWidgets.QPushButton(_("Install Tor Browser"))
+ install_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton))
+ install_button.clicked.connect(self.install)
- self.tor_update_checkbox.show()
+ # Reinstall buttons
+ reinstall_button = QtWidgets.QPushButton(_("Reinstall Tor Browser"))
+ reinstall_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton))
+ reinstall_button.clicked.connect(self.reinstall)
- # 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()
-
- # modem sound
- self.modem_checkbox = gtk.CheckButton(_("Play modem sound, because Tor is slow :]"))
- self.settings_box.pack_start(self.modem_checkbox, True, True, 0)
-
- try:
- import pygame
- if self.common.settings['modem_sound']:
- self.modem_checkbox.set_active(True)
- else:
- self.modem_checkbox.set_active(False)
- except ImportError:
- self.modem_checkbox.set_active(False)
- self.modem_checkbox.set_sensitive(False)
- self.modem_checkbox.set_tooltip_text(_("This option requires python-pygame to be installed"))
- self.modem_checkbox.show()
-
- # labels
- if(self.common.settings['installed_version']):
- self.label1 = gtk.Label(_('Installed version:\n{0}').format(self.common.settings['installed_version']))
+ if(self.common.settings['installed']):
+ install_button.hide()
+ reinstall_button.show()
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()
+ install_button.show()
+ reinstall_button.hide()
- 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()
-
- # mirrors
- self.mirrors_box = gtk.HBox(False, 10)
- self.box.pack_start(self.mirrors_box, True, True, 0)
- self.mirrors_box.show()
-
- self.mirrors_label = gtk.Label(_('Mirror'))
- self.mirrors_label.set_line_wrap(True)
- self.mirrors_box.pack_start(self.mirrors_label, True, True, 0)
- self.mirrors_label.show()
-
- self.mirrors = gtk.combo_box_new_text()
+ # Status layout
+ status_layout = QtWidgets.QVBoxLayout()
+ status_layout.addWidget(status_label)
+ status_layout.addWidget(install_button)
+ status_layout.addWidget(reinstall_button)
+
+ # Top layout
+ top_layout = QtWidgets.QHBoxLayout()
+ top_layout.addLayout(settings_layout)
+ top_layout.addLayout(status_layout)
+
+ # Mirror
+ mirror_label = QtWidgets.QLabel(_('Mirror'))
+
+ self.mirror = QtWidgets.QComboBox()
for mirror in self.common.mirrors:
- self.mirrors.append_text(mirror)
+ self.mirror.addItem(mirror)
+
if self.common.settings['mirror'] in self.common.mirrors:
- self.mirrors.set_active(self.common.mirrors.index(self.common.settings['mirror']))
- else:
- self.mirrors.set_active(0)
- self.mirrors_box.pack_start(self.mirrors, True, True, 0)
- self.mirrors.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()
-
- # UI Callback for update over tor/use system tor
- def on_system_tor_clicked(self, event):
- if self.txsocks_found:
- value = self.system_tor_checkbox.get_active()
+ self.mirror.setCurrentIndex(self.mirror.findText(self.common.settings['mirror']))
else:
- value = False
-
- self.tor_update_checkbox.set_active(value)
- self.tor_update_checkbox.set_sensitive(value)
+ self.mirror.setCurrentIndex(0)
+
+ mirror_layout = QtWidgets.QHBoxLayout()
+ mirror_layout.addWidget(mirror_label)
+ mirror_layout.addWidget(self.mirror)
+
+ # Save & Exit button
+ self.save_exit_button = QtWidgets.QPushButton(_("Save && Exit"))
+ self.save_exit_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton))
+ self.save_exit_button.clicked.connect(self.save_exit)
+
+ # Cancel button
+ self.cancel_button = QtWidgets.QPushButton(_("Cancel"))
+ self.cancel_button.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogCancelButton))
+ self.cancel_button.clicked.connect(self.close)
+
+ # Buttons layout
+ buttons_layout = QtWidgets.QHBoxLayout()
+ buttons_layout.addWidget(self.save_exit_button)
+ buttons_layout.addWidget(self.cancel_button)
+
+ # Main layout
+ layout = QtWidgets.QVBoxLayout()
+ layout.addLayout(top_layout)
+ layout.addLayout(mirror_layout)
+ layout.addLayout(buttons_layout)
+
+ central_widget = QtWidgets.QWidget()
+ central_widget.setLayout(layout)
+ self.setCentralWidget(central_widget)
+
+ # Install
+ def install(self):
+ self.save()
+ subprocess.Popen([self.common.paths['tbl_bin']])
+ self.close()
- # save and launch
- def save_launch(self, widget, data=None):
+ # Reinstall
+ def reinstall(self):
self.save()
+ shutil.rmtree(self.common.paths['tbb']['dir'])
subprocess.Popen([self.common.paths['tbl_bin']])
- self.destroy(False)
+ self.close()
- # save and exit
- def save_exit(self, widget, data=None):
+ # Save & Exit
+ def save_exit(self):
self.save()
- self.destroy(False)
+ self.close()
- # save settings
+ # Save settings
def save(self):
- # 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()
- self.common.settings['modem_sound'] = self.modem_checkbox.get_active()
+ # Checkbox options
+ self.common.settings['download_over_tor'] = self.tor_download_checkbox.isChecked()
+ self.common.settings['force_en-US'] = self.force_en_checkbox.isChecked()
+ self.common.settings['tor_socks_address'] = self.tor_addr.text()
- # figure out the selected mirror
- self.common.settings['mirror'] = self.common.mirrors[self.mirrors.get_active()]
+ # Figure out the selected mirror
+ self.common.settings['mirror'] = self.mirror.currentText()
- # save them
+ # 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()
-
-