def setUpClass(cls): bleachbit.online_update_notification_enabled = False cls.old_language = common.get_env('LANGUAGE') common.put_env('LANGUAGE', 'en') super(ExternalCommandTestCase, ExternalCommandTestCase).setUpClass() options.set('first_start', False) options.set('check_online_updates', False) # avoid pop-up window
def test_bytes_to_human(self): """Unit test for class bytes_to_human""" if 'posix' == os.name: old_locale = locale.getlocale(locale.LC_NUMERIC) locale.setlocale(locale.LC_NUMERIC, 'en_US.UTF-8') # test one-way conversion for predefined values # each test is a tuple in the format: (bytes, SI, EIC) tests = ((-1, '-1B', '-1B'), (0, '0', '0'), (1, '1B', '1B'), (1000, '1kB', '1000B'), (1024, '1kB', '1KiB'), (1110, '1.1kB', '1.1KiB'), (1000**2, '1MB', '976.6KiB'), (1024**2, '1MB', '1MiB'), (1289748, '1.3MB', '1.2MiB'), (1000**3, '1GB', '953.7MiB'), (1024**3, '1.07GB', '1GiB'), (1320702444, '1.32GB', '1.23GiB'), (1000**4, '1TB', '931.32GiB'), (1024**4, '1.1TB', '1TiB'), (1000**5, '1PB', '909.49TiB'), (1024**5, '1.13PB', '1PiB')) options.set('units_iec', True) for test in tests: iec = bytes_to_human(test[0]) self.assertEqual(test[2], iec, 'bytes_to_human(%d) IEC = %s but expected %s' % (test[0], iec, test[2])) options.set('units_iec', False) for test in tests: si = bytes_to_human(test[0]) self.assertEqual(test[1], si, 'bytes_to_human(%d) SI = %s but expected %s' % (test[0], si, test[1])) # test roundtrip conversion for random values import random for n in range(0, 1000): bytes1 = random.randrange(0, 1000 ** 4) human = bytes_to_human(bytes1) bytes2 = human_to_bytes(human) error = abs(float(bytes2 - bytes1) / bytes1) self.assertLess(abs(error), 0.01, "%d (%s) is %.2f%% different than %d" % (bytes1, human, error * 100, bytes2)) # test localization if hasattr(locale, 'format_string'): try: locale.setlocale(locale.LC_NUMERIC, 'de_DE.utf8') except: logger.warning('exception when setlocale to de_DE.utf8') else: self.assertEqual("1,01GB", bytes_to_human(1000 ** 3 + 5812389)) # clean up if 'posix' == os.name: locale.setlocale(locale.LC_NUMERIC, old_locale)
def on_window_state_event(self, widget, event): # save window state fullscreen = event.new_window_state & Gdk.WindowState.FULLSCREEN != 0 options.set("window_fullscreen", fullscreen, commit=False) maximized = event.new_window_state & Gdk.WindowState.MAXIMIZED != 0 options.set("window_maximized", maximized, commit=False) return False
def __init__(self, *args, **kwargs): super(GUI, self).__init__(*args, **kwargs) from bleachbit import RecognizeCleanerML RecognizeCleanerML.RecognizeCleanerML() register_cleaners() self.populate_window() # Redirect logging to the GUI. bb_logger = logging.getLogger('bleachbit') gtklog = GtkLoggerHandler(self.append_text) bb_logger.addHandler(gtklog) if 'nt' == os.name and 'windows_exe' == getattr(sys, 'frozen', None): # On Microsoft Windows this avoids py2exe redirecting stderr to # bleachbit.exe.log. # sys.frozen = console_exe means the console is shown from bleachbit import logger_sh bb_logger.removeHandler(logger_sh) if options.get("first_start") and 'posix' == os.name: pref = PreferencesDialog(self, self.cb_refresh_operations) pref.run() options.set('first_start', False) if bleachbit.online_update_notification_enabled and options.get("check_online_updates"): self.check_online_updates() if 'nt' == os.name: # BitDefender false positive. BitDefender didn't mark BleachBit as infected or show # anything in its log, but sqlite would fail to import unless BitDefender was in "game mode." # http://bleachbit.sourceforge.net/forum/074-fails-errors try: import sqlite3 except ImportError as e: self.append_text( _("Error loading the SQLite module: the antivirus software may be blocking it."), 'error')
def __init__(self, parent_window=None): self.parent_window = parent_window try: self.salt = options.get('hashsalt') except bleachbit.NoOptionError: self.salt = hashdigest(os.urandom(512)) options.set('hashsalt', self.salt) self.__scan()
def setUpClass(cls): super(GUITestCase, GUITestCase).setUpClass() options.set('first_start', False) options.get_tree = types.MethodType(lambda self, parent, child: False, options, Options) cls.app.register() cls.app.activate() cls.refresh_gui()
def __init__(self, parent_window=None): self.parent_window = parent_window try: self.salt = options.get('hashsalt') except bleachbit.NoOptionError: self.salt = hashdigest(str(random.random())) options.set('hashsalt', self.salt) self.__scan()
def setUpClass(cls): super(GUITestCase, GUITestCase).setUpClass() options.set('first_start', False) options.set('check_online_updates', False) # avoid pop-up window options.get_tree = types.MethodType(lambda self, parent, child: False, options) cls.app.register() cls.app.activate() cls.refresh_gui()
def test_clean_ini(self): """Unit test for clean_ini()""" print("testing test_clean_ini() with shred = False") options.set('shred', False, commit=False) test_ini_helper(self, clean_ini) print("testing test_clean_ini() with shred = True") options.set('shred', True, commit=False) test_ini_helper(self, clean_ini)
def test_clean_json(self): """Unit test for clean_json()""" print "testing test_clean_json() with shred = False" options.set('shred', False, commit=False) test_json_helper(self, clean_json) print "testing test_clean_json() with shred = True" options.set('shred', True, commit=False) test_json_helper(self, clean_json)
def test_clean_json(self): """Unit test for clean_json()""" print("testing test_clean_json() with shred = False") options.set('shred', False, commit=False) test_json_helper(self, clean_json) print("testing test_clean_json() with shred = True") options.set('shred', True, commit=False) test_json_helper(self, clean_json)
def test_clean_ini(self): """Unit test for clean_ini()""" print "testing test_clean_ini() with shred = False" options.set('shred', False, commit=False) test_ini_helper(self, clean_ini) print "testing test_clean_ini() with shred = True" options.set('shred', True, commit=False) test_ini_helper(self, clean_ini)
def cb_register_cleaners_done(self): """Called from register_cleaners()""" self.progressbar.hide() # update tree view self.tree_store.refresh_rows() # expand tree view self.view.expand_all() # Check for online updates. if not self._auto_exit and \ bleachbit.online_update_notification_enabled and \ options.get("check_online_updates") and \ not hasattr(self, 'checked_for_updates'): self.checked_for_updates = True self.check_online_updates() # Show information for first start. # (The first start flag is set also for each new version.) if options.get("first_start") and not self._auto_exit: if os.name == 'posix': self.append_text( _('Access the application menu by clicking the hamburger icon on the title bar.' )) pref = self.get_preferences_dialog() pref.run() if os.name == 'nt': self.append_text( _('Access the application menu by clicking the logo on the title bar.' )) options.set('first_start', False) if os.name == 'nt': # BitDefender false positive. BitDefender didn't mark BleachBit as infected or show # anything in its log, but sqlite would fail to import unless BitDefender was in "game mode." # http://bleachbit.sourceforge.net/forum/074-fails-errors try: import sqlite3 except ImportError as e: self.append_text( _("Error loading the SQLite module: the antivirus software may be blocking it." ), 'error') # Show notice about admin privileges. if os.name == 'posix' and os.path.expanduser('~') == '/root': self.append_text( _('You are running BleachBit with administrative privileges for cleaning shared parts of the system, and references to the user profile folder will clean only the root account.' ) + '\n') if os.name == 'nt' and options.get('shred'): from win32com.shell.shell import IsUserAnAdmin if not IsUserAnAdmin(): self.append_text( _('Run BleachBit with administrator privileges to improve the accuracy of overwriting the contents of files.' )) self.append_text('\n') # remove from idle loop (see GObject.idle_add) return False
def __init__(self, uac=True, shred_paths=None, exit=False): if uac and 'nt' == os.name and Windows.elevate_privileges(): # privileges escalated in other process sys.exit(0) if not exit: from bleachbit import RecognizeCleanerML RecognizeCleanerML.RecognizeCleanerML() register_cleaners() self.create_window() gobject.threads_init() # Redirect logging to the GUI. bb_logger = logging.getLogger('bleachbit') gtklog = GtkLoggerHandler(self.append_text) bb_logger.addHandler(gtklog) if 'nt' == os.name and 'windows_exe' == getattr(sys, 'frozen', None): # On Microsoft Windows this avoids py2exe redirecting stderr to # bleachbit.exe.log. # sys.frozen = console_exe means the console is shown from bleachbit import logger_sh bb_logger.removeHandler(logger_sh) if shred_paths: self.shred_paths(shred_paths) return if options.get("first_start") and 'posix' == os.name: pref = PreferencesDialog(self.window, self.cb_refresh_operations) pref.run() options.set('first_start', False) if bleachbit.online_update_notification_enabled and options.get( "check_online_updates"): self.check_online_updates() if 'nt' == os.name: # BitDefender false positive. BitDefender didn't mark BleachBit as infected or show # anything in its log, but sqlite would fail to import unless BitDefender was in "game mode." # https://www.bleachbit.org/forum/074-fails-errors try: import sqlite3 except ImportError: logger.exception( _("Error loading the SQLite module: the antivirus software may be blocking it." )) if 'posix' == os.name and bleachbit.expanduser('~') == '/root': self.append_text( _('You are running BleachBit with administrative privileges for cleaning shared parts of the system, and references to the user profile folder will clean only the root account.' )) if 'nt' == os.name and options.get('shred'): from win32com.shell.shell import IsUserAnAdmin if not IsUserAnAdmin(): self.append_text( _('Run BleachBit with administrator privileges to improve the accuracy of overwriting the contents of files.' )) self.append_text('\n') if exit: # This is used for automated testing of whether the GUI can start. gobject.idle_add(lambda: gtk.main_quit(), priority=gobject.PRIORITY_LOW)
def __init__(self, auto_exit, *args, **kwargs): super(GUI, self).__init__(*args, **kwargs) self.auto_exit = auto_exit self.set_wmclass(APP_NAME, APP_NAME) self.populate_window() # Redirect logging to the GUI. bb_logger = logging.getLogger('bleachbit') gtklog = GtkLoggerHandler(self.append_text) bb_logger.addHandler(gtklog) if os.name == 'nt' and getattr(sys, 'frozen', None) == 'windows_exe': # On Microsoft Windows this avoids py2exe redirecting stderr to # bleachbit.exe.log. # sys.frozen = console_exe means the console is shown from bleachbit import logger_sh bb_logger.removeHandler(logger_sh) Gtk.Settings.get_default().set_property( 'gtk-application-prefer-dark-theme', options.get('dark_mode')) if options.is_corrupt(): logger.error( _('Resetting the configuration file because it is corrupt: %s') % bleachbit.options_file) bleachbit.Options.init_configuration() if options.get("first_start") and os.name == 'posix' and not auto_exit: pref = PreferencesDialog(self, self.cb_refresh_operations) pref.run() options.set('first_start', False) if os.name == 'nt': # BitDefender false positive. BitDefender didn't mark BleachBit as infected or show # anything in its log, but sqlite would fail to import unless BitDefender was in "game mode." # http://bleachbit.sourceforge.net/forum/074-fails-errors try: import sqlite3 except ImportError as e: self.append_text( _("Error loading the SQLite module: the antivirus software may be blocking it." ), 'error') if os.name == 'posix' and bleachbit.expanduser('~') == '/root': self.append_text( _('You are running BleachBit with administrative privileges for cleaning shared parts of the system, and references to the user profile folder will clean only the root account.' )) if os.name == 'nt' and options.get('shred'): from win32com.shell.shell import IsUserAnAdmin if not IsUserAnAdmin(): self.append_text( _('Run BleachBit with administrator privileges to improve the accuracy of overwriting the contents of files.' )) self.append_text('\n') GLib.idle_add(self.cb_refresh_operations)
def test_confirm_delete(self, mock_delete_confirmation_dialog): gui = self.app._window for new_delete_confirmation in [True, False]: options.set('delete_confirmation', new_delete_confirmation, commit=False) gui._confirm_delete(False, False) # We should have a single call to delete_confirmation_dialog # only when delete_confirmation option is True. mock_delete_confirmation_dialog.assert_called_once()
def _run_shred_command(self, shred_command_string): environment_changed = False if 'BLEACHBIT_TEST_OPTIONS_DIR' not in os.environ: # We need to set env var because of the new process that executes the context menu command string common.put_env('BLEACHBIT_TEST_OPTIONS_DIR', self.tempdir) environment_changed = True options.set('delete_confirmation', False) os.system(shred_command_string) if environment_changed: # We don't want to affect other tests, executed after this one. common.put_env('BLEACHBIT_TEST_OPTIONS_DIR', None)
def setUpClass(cls): cls.old_language = common.get_env('LANGUAGE') common.put_env('LANGUAGE', 'en') super(GUITestCase, GUITestCase).setUpClass() options.set('first_start', False) options.set('check_online_updates', False) # avoid pop-up window options.get_tree = types.MethodType(lambda self, parent, child: False, options) cls.app.register() cls.app.activate() cls.refresh_gui()
def __init__(self, uac=True, shred_paths=None, exit=False): if uac and 'nt' == os.name and Windows.elevate_privileges(): # privileges escalated in other process sys.exit(0) if not exit: from bleachbit import RecognizeCleanerML RecognizeCleanerML.RecognizeCleanerML() register_cleaners() self.create_window() gobject.threads_init() # Redirect logging to the GUI. bb_logger = logging.getLogger('bleachbit') gtklog = GtkLoggerHandler(self.append_text) bb_logger.addHandler(gtklog) if 'nt' == os.name and 'windows_exe' == getattr(sys, 'frozen', None): # On Microsoft Windows this avoids py2exe redirecting stderr to # bleachbit.exe.log. # sys.frozen = console_exe means the console is shown from bleachbit import logger_sh bb_logger.removeHandler(logger_sh) if shred_paths: self.shred_paths(shred_paths) return if options.get("first_start") and 'posix' == os.name: pref = PreferencesDialog(self.window, self.cb_refresh_operations) pref.run() options.set('first_start', False) if bleachbit.online_update_notification_enabled and options.get("check_online_updates"): self.check_online_updates() if 'nt' == os.name: # BitDefender false positive. BitDefender didn't mark BleachBit as infected or show # anything in its log, but sqlite would fail to import unless BitDefender was in "game mode." # https://www.bleachbit.org/forum/074-fails-errors try: import sqlite3 except ImportError: logger.exception(_("Error loading the SQLite module: the antivirus software may be blocking it.")) if 'posix' == os.name and bleachbit.expanduser('~') == '/root': self.append_text( _('You are running BleachBit with administrative privileges for cleaning shared parts of the system, and references to the user profile folder will clean only the root account.')) if 'nt' == os.name and options.get('shred'): from win32com.shell.shell import IsUserAnAdmin if not IsUserAnAdmin(): self.append_text( _('Run BleachBit with administrator privileges to improve the accuracy of overwriting the contents of files.')) self.append_text('\n') if exit: # This is used for automated testing of whether the GUI can start. gobject.idle_add( lambda: gtk.main_quit(), priority=gobject.PRIORITY_LOW)
def on_configure_event(self, widget, event): (x, y) = self.get_position() (width, height) = self.get_size() # fixup maximized window position: # on Windows if a window is maximized on a secondary monitor it is moved off the screen if 'nt' == os.name: window = self.get_window() if window.get_state() & Gdk.WindowState.MAXIMIZED != 0: screen = self.get_screen() monitor_num = screen.get_monitor_at_window(window) g = screen.get_monitor_geometry(monitor_num) if x < g.x or x >= g.x + g.width or y < g.y or y >= g.y + g.height: logger.debug( "Maximized window {}+{}: monitor ({}) geometry = {}+{}" .format((x, y), (width, height), monitor_num, (g.x, g.y), (g.width, g.height))) self.move(g.x, g.y) return True # save window position and size options.set("window_x", x, commit=False) options.set("window_y", y, commit=False) options.set("window_width", width, commit=False) options.set("window_height", height, commit=False) return False
def _test_as_non_admin_with_context_menu_path(self, fn_prefix): """ This tests covers elevate_privileges in the case where we pretend that we are not admin. """ from bleachbit.Options import options file_to_shred = self.mkstemp(prefix=fn_prefix) self.assertExists(file_to_shred) original = bleachbit.Windows.shell.ShellExecuteEx def shell_execute_synchronous(lpVerb='', lpFile='', lpParameters='', nShow=''): """ We need a synchronous call the ShellExecuteEx so we can assert after it finishes. """ from win32com.shell import shell, shellcon import win32event bleachbit.Windows.shell.ShellExecuteEx = original rc = shell.ShellExecuteEx( lpVerb=lpVerb, lpFile=lpFile, lpParameters=lpParameters, nShow=nShow, fMask=shellcon.SEE_MASK_NOCLOSEPROCESS, ) hproc = rc['hProcess'] win32event.WaitForSingleObject(hproc, win32event.INFINITE) return rc options.set('delete_confirmation', False) # We redirect the ShellExecuteEx call like this because if we do it in a mock we enter recursion # because we call ShellExecuteEx in shell_execute_synchronous bleachbit.Windows.shell.ShellExecuteEx = shell_execute_synchronous with mock.patch('bleachbit.Windows.shell.IsUserAnAdmin', return_value=False): with mock.patch('bleachbit.GUI.sys.exit'): with mock.patch( 'bleachbit.Windows.sys.argv', ['dummy-arg', '--context-menu', file_to_shred]): Bleachbit(auto_exit=True, shred_paths=[file_to_shred], uac=True) self.assertNotExists(file_to_shred)
def on_configure_event(self, widget, event): # save window position and size if self.is_maximized(): return (x, y) = self.get_position() options.set("window_x", x, commit=False) options.set("window_y", y, commit=False) (width, height) = self.get_size() options.set("window_width", width, commit=False) options.set("window_height", height, commit=False) return False
def _context_helper(self, fn_prefix): """Unit test for 'Shred with BleachBit' Windows Explorer context menu command""" # This test is more likely an integration test as it imitates user behavior. # It could be interpreted as TestCLI->test_gui_no-uac_shred_exit # but it is more explicit to have it here as a separate case. # It covers a single case where one file is shred without delete confirmation dialog. def set_curdir_to_bleachbit(): os.curdir = os.path.split(__file__)[0] os.curdir = os.path.split(os.curdir)[0] file_to_shred = self.mkstemp(prefix=fn_prefix) print('file_to_shred = {}'.format(file_to_shred)) self.assertExists(file_to_shred) shred_command_key = '{}\\command'.format(SHRED_REGEX_KEY) shred_command_string = common.get_winregistry_value( winreg.HKEY_CLASSES_ROOT, shred_command_key) if shred_command_string is None: # Use main .py file when the application is not installed and there is no .exe file # and corresponding registry entry. shred_command_string = r'{} bleachbit.py --gui --no-uac --shred --exit "{}"'.format( sys.executable, file_to_shred) set_curdir_to_bleachbit() else: self.assertTrue('"%1"' in shred_command_string) shred_command_string = shred_command_string.replace( '"%1"', file_to_shred) delete_confirmation_saved_state = options.get('delete_confirmation') options.set('delete_confirmation', False) os.system(shred_command_string) options.set('delete_confirmation', delete_confirmation_saved_state) self.assertNotExists(file_to_shred) opened_windows_titles = common.get_opened_windows_titles() # Assert that the Bleachbit window has been closed after the context menu operation had finished. self.assertFalse( any([ 'BleachBit' == window_title for window_title in opened_windows_titles ]))
def sqlite_clean_helper(self, sql, fn, clean_func, check_func=None, setup_func=None): """Helper for cleaning special SQLite cleaning""" self.assertFalse( sql and fn, "sql and fn are mutually exclusive ways to create the data") if fn: filename = os.path.join(self.dir_base, fn) if not os.path.exists(filename): import pdb pdb.set_trace() self.assert_(os.path.exists(filename)) # create sqlite file if sql: # create test file tmpdir = tempfile.mkdtemp('bleachbit-sqlite-test') (fd, filename) = tempfile.mkstemp(dir=tmpdir) os.close(fd) # additional setup if setup_func: setup_func(filename) # before SQL creation executed, cleaning should fail self.assertRaises(sqlite3.DatabaseError, clean_func, filename) # create bleachbit.FileUtilities.execute_sqlite3(filename, sql) self.assert_(os.path.exists(filename)) # clean the file old_shred = options.get('shred') options.set('shred', False, commit=False) self.assertFalse(options.get('shred')) clean_func(filename) options.set('shred', True, commit=False) self.assertTrue(options.get('shred')) options.set('shred', old_shred, commit=False) clean_func(filename) self.assert_(os.path.exists(filename)) # check if check_func: check_func(self, filename) # tear down bleachbit.FileUtilities.delete(filename) self.assert_(not os.path.exists(filename))
def on_configure_event(self, widget, event): # save window position and size screen = self.get_screen() (screen_w, screen_h) = (screen.get_width(), screen.get_height()) (x, y) = self.get_position() if x >= screen_w or y >= screen_h: monitor = screen.get_monitor_at_window(self.get_window()) g = screen.get_monitor_geometry(monitor) print( "Fixup moving the window off the screen: window (x, y) = {}, screen (w, h) = {}, monitor (x, y) = {}, (w, h) = {}" .format((x, y), (screen_w, screen_h), (g.x, g.y), (g.width, g.height))) self.move(g.x, g.y) return True options.set("window_x", x, commit=False) options.set("window_y", y, commit=False) (width, height) = self.get_size() options.set("window_width", width, commit=False) options.set("window_height", height, commit=False) return False
def sqlite_clean_helper(self, sql, fn, clean_func, check_func=None, setup_func=None): """Helper for cleaning special SQLite cleaning""" self.assertFalse( sql and fn, "sql and fn are mutually exclusive ways to create the data") if fn: filename = os.path.normpath(os.path.join(self.dir_base, fn)) self.assertExists(filename) # create sqlite file elif sql: # create test file filename = self.mkstemp(prefix='bleachbit-test-sqlite') # additional setup if setup_func: setup_func(filename) # before SQL creation executed, cleaning should fail self.assertRaises(sqlite3.DatabaseError, clean_func, filename) # create FileUtilities.execute_sqlite3(filename, sql) self.assertExists(filename) else: raise RuntimeError('neither fn nor sql supplied') # clean the file old_shred = options.get('shred') options.set('shred', False, commit=False) self.assertFalse(options.get('shred')) clean_func(filename) options.set('shred', True, commit=False) self.assertTrue(options.get('shred')) options.set('shred', old_shred, commit=False) clean_func(filename) self.assertExists(filename) # check if check_func: check_func(self, filename) # tear down FileUtilities.delete(filename) self.assertNotExists(filename)
def sqlite_clean_helper( self, sql, fn, clean_func, check_func=None, setup_func=None): """Helper for cleaning special SQLite cleaning""" self.assertFalse( sql and fn, "sql and fn are mutually exclusive ways to create the data") if fn: filename = os.path.join(self.dir_base, fn) if not os.path.exists(filename): import pdb pdb.set_trace() self.assert_(os.path.exists(filename)) # create sqlite file if sql: # create test file tmpdir = tempfile.mkdtemp('bleachbit-sqlite-test') (fd, filename) = tempfile.mkstemp(dir=tmpdir) os.close(fd) # additional setup if setup_func: setup_func(filename) # before SQL creation executed, cleaning should fail self.assertRaises(sqlite3.DatabaseError, clean_func, filename) # create bleachbit.FileUtilities.execute_sqlite3(filename, sql) self.assert_(os.path.exists(filename)) # clean the file old_shred = options.get('shred') options.set('shred', False, commit=False) self.assertFalse(options.get('shred')) clean_func(filename) options.set('shred', True, commit=False) self.assertTrue(options.get('shred')) options.set('shred', old_shred, commit=False) clean_func(filename) self.assert_(os.path.exists(filename)) # check if check_func: check_func(self, filename) # tear down bleachbit.FileUtilities.delete(filename) self.assert_(not os.path.exists(filename))
def sqlite_clean_helper(self, sql, fn, clean_func, check_func=None, setup_func=None): """Helper for cleaning special SQLite cleaning""" self.assertFalse(sql and fn, "sql and fn are mutually exclusive ways to create the data") if fn: filename = os.path.normpath(os.path.join(self.dir_base, fn)) self.assertExists(filename) # create sqlite file elif sql: # create test file filename = self.mkstemp(prefix='bleachbit-test-sqlite') # additional setup if setup_func: setup_func(filename) # before SQL creation executed, cleaning should fail self.assertRaises(sqlite3.DatabaseError, clean_func, filename) # create FileUtilities.execute_sqlite3(filename, sql) self.assertExists(filename) else: raise RuntimeError('neither fn nor sql supplied') # clean the file old_shred = options.get('shred') options.set('shred', False, commit=False) self.assertFalse(options.get('shred')) clean_func(filename) options.set('shred', True, commit=False) self.assertTrue(options.get('shred')) options.set('shred', old_shred, commit=False) clean_func(filename) self.assertExists(filename) # check if check_func: check_func(self, filename) # tear down FileUtilities.delete(filename) self.assertNotExists(filename)
def __general_page(self): """Return a widget containing the general page""" if 'nt' == os.name: swcc = Windows.start_with_computer_check if 'posix' == os.name: swcc = Unix.start_with_computer_check options.set('auto_start', swcc()) vbox = gtk.VBox() if online_update_notification_enabled: cb_updates = gtk.CheckButton( _("Check periodically for software updates via the Internet")) cb_updates.set_active(options.get('check_online_updates')) cb_updates.connect( 'toggled', self.__toggle_callback, 'check_online_updates') cb_updates.set_tooltip_text( _("If an update is found, you will be given the option to view information about it. Then, you may manually download and install the update.")) vbox.pack_start(cb_updates, False) updates_box = gtk.VBox() updates_box.set_border_width(10) self.cb_beta = gtk.CheckButton(_("Check for new beta releases")) self.cb_beta.set_active(options.get('check_beta')) self.cb_beta.set_sensitive(options.get('check_online_updates')) self.cb_beta.connect( 'toggled', self.__toggle_callback, 'check_beta') updates_box.pack_start(self.cb_beta, False) if 'nt' == os.name: self.cb_winapp2 = gtk.CheckButton( _("Download and update cleaners from community (winapp2.ini)")) self.cb_winapp2.set_active(options.get('update_winapp2')) self.cb_winapp2.set_sensitive( options.get('check_online_updates')) self.cb_winapp2.connect( 'toggled', self.__toggle_callback, 'update_winapp2') updates_box.pack_start(self.cb_winapp2, False) vbox.pack_start(updates_box, False) # TRANSLATORS: This means to hide cleaners which would do # nothing. For example, if Firefox were never used on # this system, this option would hide Firefox to simplify # the list of cleaners. cb_auto_hide = gtk.CheckButton(_("Hide irrelevant cleaners")) cb_auto_hide.set_active(options.get('auto_hide')) cb_auto_hide.connect('toggled', self.__toggle_callback, 'auto_hide') vbox.pack_start(cb_auto_hide, False) # TRANSLATORS: Overwriting is the same as shredding. It is a way # to prevent recovery of the data. You could also translate # 'Shred files to prevent recovery.' cb_shred = gtk.CheckButton(_("Overwrite contents of files to prevent recovery")) cb_shred.set_active(options.get('shred')) cb_shred.connect('toggled', self.__toggle_callback, 'shred') cb_shred.set_tooltip_text( _("Overwriting is ineffective on some file systems and with certain BleachBit operations. Overwriting is significantly slower.")) vbox.pack_start(cb_shred, False) cb_start = gtk.CheckButton(_("Start BleachBit with computer")) cb_start.set_active(options.get('auto_start')) cb_start.connect('toggled', self.__toggle_callback, 'auto_start') vbox.pack_start(cb_start, False) # Close the application after cleaning is complete. cb_exit = gtk.CheckButton(_("Exit after cleaning")) cb_exit.set_active(options.get('exit_done')) cb_exit.connect('toggled', self.__toggle_callback, 'exit_done') vbox.pack_start(cb_exit, False) # Disable delete confirmation message. cb_popup = gtk.CheckButton(_("Confirm before delete")) cb_popup.set_active(options.get('delete_confirmation')) cb_popup.connect( 'toggled', self.__toggle_callback, 'delete_confirmation') vbox.pack_start(cb_popup, False) # Use base 1000 over 1024? cb_units_iec = gtk.CheckButton( _("Use IEC sizes (1 KiB = 1024 bytes) instead of SI (1 kB = 1000 bytes)")) cb_units_iec.set_active(options.get("units_iec")) cb_units_iec.connect('toggled', self.__toggle_callback, 'units_iec') vbox.pack_start(cb_units_iec, False) return vbox
def __init__(self, auto_exit, *args, **kwargs): super(GUI, self).__init__(*args, **kwargs) self.auto_exit = auto_exit self.set_wmclass(APP_NAME, APP_NAME) self.populate_window() # Redirect logging to the GUI. bb_logger = logging.getLogger('bleachbit') from bleachbit.Log import GtkLoggerHandler self.gtklog = GtkLoggerHandler(self.append_text) bb_logger.addHandler(self.gtklog) # process any delayed logs from bleachbit.Log import DelayLog if isinstance(sys.stderr, DelayLog): for msg in sys.stderr.read(): self.append_text(msg) # if stderr was redirected - keep redirecting it sys.stderr = self.gtklog Gtk.Settings.get_default().set_property( 'gtk-application-prefer-dark-theme', options.get('dark_mode')) if options.is_corrupt(): logger.error( _('Resetting the configuration file because it is corrupt: %s') % bleachbit.options_file) bleachbit.Options.init_configuration() if options.get("first_start") and not auto_exit: if os.name == 'posix': self.append_text( _('Access the application menu by clicking the hamburger icon on the title bar.' )) pref = PreferencesDialog(self, self.cb_refresh_operations) pref.run() if os.name == 'nt': self.append_text( _('Access the application menu by clicking the logo on the title bar.' )) options.set('first_start', False) if os.name == 'nt': # BitDefender false positive. BitDefender didn't mark BleachBit as infected or show # anything in its log, but sqlite would fail to import unless BitDefender was in "game mode." # http://bleachbit.sourceforge.net/forum/074-fails-errors try: import sqlite3 except ImportError as e: self.append_text( _("Error loading the SQLite module: the antivirus software may be blocking it." ), 'error') if os.name == 'posix' and bleachbit.expanduser('~') == '/root': self.append_text( _('You are running BleachBit with administrative privileges for cleaning shared parts of the system, and references to the user profile folder will clean only the root account.' )) if os.name == 'nt' and options.get('shred'): from win32com.shell.shell import IsUserAnAdmin if not IsUserAnAdmin(): self.append_text( _('Run BleachBit with administrator privileges to improve the accuracy of overwriting the contents of files.' )) self.append_text('\n') GLib.idle_add(self.cb_refresh_operations)
def __general_page(self): //'nt' == os.name이면 Windows파일 import하여 swc = Windows.start_with_computer_check 선언 if 'nt' == os.name: swcc = Windows.start_with_computer_check // 'posix' == os.name이면 Unix파일 import하여 swc = Unix.start_with_computer_check 선언 if 'posix' == os.name: swcc = Unix.start_with_computer_check options.set('auto_start', swcc()) vbox = gtk.VBox() // online_update_notification_enabled 이면 if online_update_notification_enabled: cb_updates = gtk.CheckButton( _("Check periodically for software updates via the Internet")) cb_updates.set_active(options.get('check_online_updates')) cb_updates.connect( 'toggled', self.__toggle_callback, 'check_online_updates') cb_updates.set_tooltip_text( _("If an update is found, you will be given the option to view information about it. Then, you may manually download and install the update.")) vbox.pack_start(cb_updates, False) updates_box = gtk.VBox() updates_box.set_border_width(10) self.cb_beta = gtk.CheckButton(_("Check for new beta releases")) self.cb_beta.set_active(options.get('check_beta')) self.cb_beta.set_sensitive(options.get('check_online_updates')) self.cb_beta.connect( 'toggled', self.__toggle_callback, 'check_beta') updates_box.pack_start(self.cb_beta, False) if 'nt' == os.name: self.cb_winapp2 = gtk.CheckButton( _("Download and update cleaners from community (winapp2.ini)")) self.cb_winapp2.set_active(options.get('update_winapp2')) self.cb_winapp2.set_sensitive( options.get('check_online_updates')) self.cb_winapp2.connect( 'toggled', self.__toggle_callback, 'update_winapp2') updates_box.pack_start(self.cb_winapp2, False) vbox.pack_start(updates_box, False) // '무관한 클리너 숨김' 버튼 생성 및 연결 cb_auto_hide = gtk.CheckButton(_("Hide irrelevant cleaners")) cb_auto_hide.set_active(options.get('auto_hide')) cb_auto_hide.connect('toggled', self.__toggle_callback, 'auto_hide') vbox.pack_start(cb_auto_hide, False) // '파일 삭제 기능' 버튼 생성 및 연결 cb_shred = gtk.CheckButton(_("Overwrite contents of files to prevent recovery")) cb_shred.set_active(options.get('shred')) cb_shred.connect('toggled', self.__toggle_callback, 'shred') cb_shred.set_tooltip_text( _("Overwriting is ineffective on some file systems and with certain BleachBit operations. Overwriting is significantly slower.")) vbox.pack_start(cb_shred, False) // '블리치비트 시작' 버튼 생성 및 연결 cb_start = gtk.CheckButton(_("Start BleachBit with computer")) cb_start.set_active(options.get('auto_start')) cb_start.connect('toggled', self.__toggle_callback, 'auto_start') vbox.pack_start(cb_start, False) // 클리너 완료 후 프로그램 종료 버튼 생성 및 연결 cb_exit = gtk.CheckButton(_("Exit after cleaning")) cb_exit.set_active(options.get('exit_done')) cb_exit.connect('toggled', self.__toggle_callback, 'exit_done') vbox.pack_start(cb_exit, False) // 삭제 전 확인 버튼 생성 및 연결 cb_popup = gtk.CheckButton(_("Confirm before delete")) cb_popup.set_active(options.get('delete_confirmation')) cb_popup.connect( 'toggled', self.__toggle_callback, 'delete_confirmation') vbox.pack_start(cb_popup, False) cb_units_iec = gtk.CheckButton( _("Use IEC sizes (1 KiB = 1024 bytes) instead of SI (1 kB = 1000 bytes)")) cb_units_iec.set_active(options.get("units_iec")) cb_units_iec.connect('toggled', self.__toggle_callback, 'units_iec') vbox.pack_start(cb_units_iec, False) return vbox
def __general_page(self): """Return a widget containing the general page""" if 'nt' == os.name: swcc = Windows.start_with_computer_check if 'posix' == os.name: swcc = Unix.start_with_computer_check options.set('auto_start', swcc()) vbox = gtk.VBox() if online_update_notification_enabled: cb_updates = gtk.CheckButton( _("Check periodically for software updates via the Internet")) cb_updates.set_active(options.get('check_online_updates')) cb_updates.connect('toggled', self.__toggle_callback, 'check_online_updates') cb_updates.set_tooltip_text( _("If an update is found, you will be given the option to view information about it. Then, you may manually download and install the update." )) vbox.pack_start(cb_updates, False) updates_box = gtk.VBox() updates_box.set_border_width(10) self.cb_beta = gtk.CheckButton(_("Check for new beta releases")) self.cb_beta.set_active(options.get('check_beta')) self.cb_beta.set_sensitive(options.get('check_online_updates')) self.cb_beta.connect('toggled', self.__toggle_callback, 'check_beta') updates_box.pack_start(self.cb_beta, False) if 'nt' == os.name: self.cb_winapp2 = gtk.CheckButton( _("Download and update cleaners from community (winapp2.ini)" )) self.cb_winapp2.set_active(options.get('update_winapp2')) self.cb_winapp2.set_sensitive( options.get('check_online_updates')) self.cb_winapp2.connect('toggled', self.__toggle_callback, 'update_winapp2') updates_box.pack_start(self.cb_winapp2, False) vbox.pack_start(updates_box, False) # TRANSLATORS: This means to hide cleaners which would do # nothing. For example, if Firefox were never used on # this system, this option would hide Firefox to simplify # the list of cleaners. cb_auto_hide = gtk.CheckButton(_("Hide irrelevant cleaners")) cb_auto_hide.set_active(options.get('auto_hide')) cb_auto_hide.connect('toggled', self.__toggle_callback, 'auto_hide') vbox.pack_start(cb_auto_hide, False) # TRANSLATORS: Overwriting is the same as shredding. It is a way # to prevent recovery of the data. You could also translate # 'Shred files to prevent recovery.' cb_shred = gtk.CheckButton( _("Overwrite contents of files to prevent recovery")) cb_shred.set_active(options.get('shred')) cb_shred.connect('toggled', self.__toggle_callback, 'shred') cb_shred.set_tooltip_text( _("Overwriting is ineffective on some file systems and with certain BleachBit operations. Overwriting is significantly slower." )) vbox.pack_start(cb_shred, False) cb_start = gtk.CheckButton(_("Start BleachBit with computer")) cb_start.set_active(options.get('auto_start')) cb_start.connect('toggled', self.__toggle_callback, 'auto_start') vbox.pack_start(cb_start, False) # Close the application after cleaning is complete. cb_exit = gtk.CheckButton(_("Exit after cleaning")) cb_exit.set_active(options.get('exit_done')) cb_exit.connect('toggled', self.__toggle_callback, 'exit_done') vbox.pack_start(cb_exit, False) # Close the running application and continue cleaning. cb_exit = gtk.CheckButton(_("Close Running Application")) cb_exit.set_active(options.get('close_run')) cb_exit.connect('toggled', self.__toggle_callback, 'close_run') vbox.pack_start(cb_exit, False) # Disable delete confirmation message. cb_popup = gtk.CheckButton(_("Confirm before delete")) cb_popup.set_active(options.get('delete_confirmation')) cb_popup.connect('toggled', self.__toggle_callback, 'delete_confirmation') vbox.pack_start(cb_popup, False) # Use base 1000 over 1024? cb_units_iec = gtk.CheckButton( _("Use IEC sizes (1 KiB = 1024 bytes) instead of SI (1 kB = 1000 bytes)" )) cb_units_iec.set_active(options.get("units_iec")) cb_units_iec.connect('toggled', self.__toggle_callback, 'units_iec') vbox.pack_start(cb_units_iec, False) return vbox