Пример #1
0
def update_dialog(parent, updates):
    """Updates contains the version numbers and URLs"""
    import gtk
    from GuiBasic import open_url
    dlg = gtk.Dialog(title=_("Update BleachBit"),
                     parent=parent,
                     flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
    dlg.set_default_size(250, 125)

    label = gtk.Label(_("A new version is available."))
    dlg.vbox.pack_start(label)

    for update in updates:
        ver = update[0]
        url = update[1]
        box_update = gtk.HBox()
        # TRANSLATORS: %s expands to version such as '0.8.4' or '0.8.5beta' or
        # similar
        button_stable = gtk.Button(_("Update to version %s") % ver)
        button_stable.connect(
            'clicked', lambda dummy: open_url(url, parent, False))
        button_stable.connect('clicked', lambda dummy: dlg.response(0))
        box_update.pack_start(button_stable, False, padding=10)
        dlg.vbox.pack_start(box_update, False)

    dlg.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)

    dlg.show_all()
    dlg.run()
    dlg.destroy()

    return False
Пример #2
0
def open_url(url, parent_window=None, prompt=True):
    """Open an HTTP URL.  Try to run as non-root."""
    # drop privileges so the web browser is running as a normal process
    if 'posix' == os.name and 0 == os.getuid():
        msg = _(
            "Because you are running as root, please manually open this link in a web browser:\n%s") % url
        message_dialog(None, msg, gtk.MESSAGE_INFO)
        return
    if prompt:
        # find hostname
        import re
        ret = re.search('^http(s)?://([a-z\.]+)', url)
        if None == ret:
            host = url
        else:
            host = ret.group(2)
        # TRANSLATORS: %s expands to bleachbit.sourceforge.net or similar
        msg = _("Open web browser to %s?") % host
        resp = message_dialog(parent_window, msg,
                              gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL)
        if gtk.RESPONSE_OK != resp:
            return
    # open web browser
    if 'nt' == os.name:
        # in gtk.show_uri() avoid 'glib.GError: No application is registered as
        # handling this file'
        import webbrowser
        webbrowser.open(url)
    else:
        gtk.show_uri(None, url, gtk.gdk.CURRENT_TIME)
Пример #3
0
 def execute(self, really_delete):
     """Make changes and return results"""
     if FileUtilities.whitelisted(self.path):
         yield whitelist(self.path)
         return
     ret = {
         # TRANSLATORS: This is the label in the log indicating will be
         # deleted (for previews) or was actually deleted
         'label': _('Delete'),
         'n_deleted': 1,
         'n_special': 0,
         'path': self.path,
         'size': FileUtilities.getsize(self.path)}
     if really_delete:
         try:
             FileUtilities.delete(self.path, self.shred)
         except WindowsError, e:
             # WindowsError: [Error 32] The process cannot access the file because it is being
             # used by another process: u'C:\\Documents and
             # Settings\\username\\Cookies\\index.dat'
             if 32 != e.winerror and 5 != e.winerror:
                 raise
             try:
                 Windows.delete_locked_file(self.path)
             except:
                 raise
             else:
                 # TRANSLATORS: The file will be deleted when the
                 # system reboots
                 ret['label'] = _('Mark for deletion')
Пример #4
0
    def context_menu_event(self, treeview, event):
        """When user right clicks on the tree view"""
        if event.button != 3:
            return False
        pathinfo = treeview.get_path_at_pos(int(event.x), int(event.y))
        if None == pathinfo:
            return False
        path, col, cellx, celly = pathinfo
        treeview.grab_focus()
        treeview.set_cursor(path, col, 0)
        # context menu applies only to children, not parents
        if 2 != len(path):
            return False
        # find the seleted option
        model = treeview.get_model()
        option_id = model[path][2]
        cleaner_id = model[path[0]][2]
        cleaner_name = model[path[0]][0]
        # make a menu
        menu = gtk.Menu()
        # TRANSLATORS: this is the context menu
        preview_item = gtk.MenuItem(_("Preview"))
        preview_item.connect("activate", self.cb_run_option, False, cleaner_id, option_id)
        menu.append(preview_item)
        # TRANSLATORS: this is the context menu
        clean_item = gtk.MenuItem(_("Clean"))
        clean_item.connect("activate", self.cb_run_option, True, cleaner_id, option_id)
        menu.append(clean_item)

        # show the context menu
        menu.attach_to_widget(treeview, menu.destroy)
        menu.show_all()
        menu.popup(None, None, None, event.button, event.time)
        return True
Пример #5
0
def delete_confirmation_dialog(parent, mention_preview):
    """Return boolean whether OK to delete files."""
    dialog = gtk.Dialog(title=_("Delete confirmation"), parent=parent,
                        flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
    dialog.set_default_size(300, -1)

    hbox = gtk.HBox(homogeneous=False, spacing=10)
    icon = gtk.Image()
    icon.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
    hbox.pack_start(icon, False)
    if mention_preview:
        question_text = _(
            "Are you sure you want to permanently delete files according to the selected operations?  The actual files that will be deleted may have changed since you ran the preview.")
    else:
        question_text = _(
            "Are you sure you want to permanently delete these files?")

    question = gtk.Label(question_text)
    question.set_line_wrap(True)
    hbox.pack_start(question, False)
    dialog.vbox.pack_start(hbox, False)
    dialog.vbox.set_spacing(10)

    dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
    dialog.add_button(gtk.STOCK_DELETE, gtk.RESPONSE_ACCEPT)
    dialog.set_default_response(gtk.RESPONSE_CANCEL)

    dialog.show_all()
    ret = dialog.run()
    dialog.destroy()
    return ret == gtk.RESPONSE_ACCEPT
Пример #6
0
def yum_clean():
    """Run 'yum clean all' and return size in bytes recovered"""
    if os.path.exists('/var/run/yum.pid'):
        msg = _(
            "%s cannot be cleaned because it is currently running.  Close it, and try again.") % "Yum"
        raise RuntimeError(msg)
    if not FileUtilities.exe_exists('yum'):
        raise RuntimeError(_('Executable not found: %s') % 'yum')
    old_size = FileUtilities.getsizedir('/var/cache/yum')
    args = ['yum', "--enablerepo=*", 'clean', 'all']
    p = subprocess.Popen(args, stderr=subprocess.STDOUT,
                         stdout=subprocess.PIPE)
    non_blank_line = ""
    while True:
        line = p.stdout.readline().replace("\n", "")
        if len(line) > 2:
            non_blank_line = line
        if -1 != line.find('You need to be root'):
            # Seen before Fedora 13
            raise RuntimeError(line)
        if -1 != line.find('Cannot remove rpmdb file'):
            # Since first in Fedora 13
            raise RuntimeError(line)
        if -1 != line.find('Another app is currently holding'):
            print "debug: yum: '%s'" % line
            old_size = FileUtilities.getsizedir('/var/cache/yum')
        if "" == line and p.poll() != None:
            break
    print 'debug: yum process return code = %d' % p.returncode
    if p.returncode > 0:
        raise RuntimeError(non_blank_line)
    new_size = FileUtilities.getsizedir('/var/cache/yum')
    return old_size - new_size
Пример #7
0
    def create_toolbar(self):
        """Create the toolbar"""
        toolbar = gtk.Toolbar()

        # create the preview button
        preview_icon = gtk.Image()
        preview_icon.set_from_stock(
            gtk.STOCK_FIND, gtk.ICON_SIZE_LARGE_TOOLBAR)
        # TRANSLATORS: This is the preview button on the main window.  It
        # previews changes.
        preview_button = gtk.ToolButton(
            icon_widget=preview_icon, label=_p('button', "Preview"))
        preview_button.connect(
            "clicked", lambda *dummy: self.preview_or_run_operations(False))
        toolbar.insert(preview_button, -1)
        preview_button.set_tooltip_text(
            _("Preview files in the selected operations (without deleting any files)"))
        preview_button.set_is_important(True)

        # create the delete button
        icon = gtk.Image()
        icon.set_from_stock(gtk.STOCK_DELETE, gtk.ICON_SIZE_LARGE_TOOLBAR)
        # TRANSLATORS: This is the clean button on the main window.
        # It makes permanent changes: usually deleting files, sometimes
        # altering them.
        run_button = gtk.ToolButton(
            icon_widget=icon, label=_p("button", "Clean"))
        run_button.connect("clicked", self.run_operations)
        toolbar.insert(run_button, -1)
        run_button.set_tooltip_text(
            _("Clean files in the selected operations"))
        run_button.set_is_important(True)

        return toolbar
Пример #8
0
    def worker_done(self, worker, really_delete):
        """Callback for when Worker is done"""
        self.progressbar.set_text("")
        self.progressbar.set_fraction(1)
        if not self.stop_now:
            self.progressbar.set_text(_("Done."))
        else:
            self.progressbar.set_text(_("Stopped."))
        self.textview.scroll_mark_onscreen(self.textbuffer.get_insert())
        self.set_sensitive(True)
        
        # Close the program after cleaning is completed.
        # if the option is selected under preference.
        
        if really_delete:
            if options.get("exit_done"):
                sys.exit()

        # notification for long-running process
        elapsed = (time.time() - self.start_time)
        print 'debug: elapsed time: %d seconds' % elapsed
        if elapsed < 10 or self.window.is_active():
            return
        try:
            import pynotify
        except:
            print "debug: pynotify not available"
        else:
            if pynotify.init(APP_NAME):
                notify = pynotify.Notification('BleachBit', _("Done."),
                                               icon='bleachbit')
                notify.show()
                notify.set_timeout(10000)
Пример #9
0
 def about(self, __event):
     """Create and show the about dialog"""
     if 'nt' != os.name and (2, 16, 6) != gtk.gtk_version:
         # workaround for broken GTK+
         # (https://bugs.launchpad.net/bleachbit/+bug/797012)
         gtk.about_dialog_set_url_hook(lambda dialog,
                                       link: GuiBasic.open_url(link, self.window, False))
     dialog = gtk.AboutDialog()
     dialog.set_comments(_("Program to clean unnecessary files"))
     dialog.set_copyright("Copyright (C) 2014 Andrew Ziem")
     try:
         dialog.set_license(open(license_filename).read())
     except:
         dialog.set_license(
             _("GNU General Public License version 3 or later.\nSee http://www.gnu.org/licenses/gpl-3.0.txt"))
     dialog.set_name(APP_NAME)
     # TRANSLATORS: Maintain the names of translators here.
     # Launchpad does this automatically for translations
     # typed in Launchpad. This is a special string shown
     # in the 'About' box.
     dialog.set_translator_credits(_("translator-credits"))
     dialog.set_version(APP_VERSION)
     dialog.set_website(APP_URL)
     dialog.set_transient_for(self.window)
     if appicon_path and os.path.exists(appicon_path):
         icon = gtk.gdk.pixbuf_new_from_file(appicon_path)
         dialog.set_logo(icon)
     dialog.run()
     dialog.hide()
Пример #10
0
def args_to_operations(args, preset):
    """Read arguments and return list of operations"""
    register_cleaners()
    operations = {}
    if preset:
        # restore presets from the GUI
        for key in sorted(backends):
            c_id = backends[key].get_id()
            for (o_id, o_name) in backends[key].get_options():
                if Options.options.get_tree(c_id, o_id):
                    args.append('.'.join([c_id, o_id]))
    for arg in args:
        if 2 != len(arg.split('.')):
            print _("not a valid cleaner: %s") % arg
            continue
        (cleaner_id, option_id) = arg.split('.')
        # enable all options (for example, firefox.*)
        if '*' == option_id:
            if operations.has_key(cleaner_id):
                del operations[cleaner_id]
            operations[cleaner_id] = []
            for (option_id2, o_name) in backends[cleaner_id].get_options():
                operations[cleaner_id].append(option_id2)
            continue
        # add the specified option
        if not operations.has_key(cleaner_id):
            operations[cleaner_id] = []
        if not option_id in operations[cleaner_id]:
            operations[cleaner_id].append(option_id)
    for (k, v) in operations.iteritems():
        operations[k] = sorted(v)
    return operations
Пример #11
0
 def add_custom_file_cb(button):
     """Callback for adding a file"""
     title = _("Choose a file")
     pathname = GuiBasic.browse_file(self.parent, title)
     if pathname:
         for this_pathname in pathnames:
             if pathname == this_pathname[1]:
                 print "warning: '%s' already exists in whitelist" % pathname
                 return
         liststore.append([_('File'), pathname])
         pathnames.append(['file', pathname])
         options.set_custom_paths(pathnames)
Пример #12
0
    def __init__(self):
        Cleaner.__init__(self)
        self.options = {}
        self.add_option('cache', _('Cache'), _('Delete the cache'))
        self.add_option('recent_documents', _('Most recently used'), _("Delete the list of recently used documents"))

        # reference: http://katana.oooninja.com/w/editions_of_openoffice.org
        if 'posix' == os.name:
            self.prefixes = [ "~/.ooo-2.0", "~/.openoffice.org2", "~/.openoffice.org2.0", "~/.openoffice.org/3" ]
            self.prefixes += [ "~/.ooo-dev3" ]
        if 'nt' == os.name:
            self.prefixes = [ "$APPDATA\\OpenOffice.org\\3", "$APPDATA\\OpenOffice.org2" ]
Пример #13
0
 def add_custom_folder_cb(button):
     """Callback for adding a folder"""
     title = _("Choose a folder")
     pathname = GuiBasic.browse_folder(self.parent, title,
                                       multiple=False, stock_button=gtk.STOCK_ADD)
     if pathname:
         for this_pathname in pathnames:
             if pathname == this_pathname[1]:
                 print "warning: '%s' already exists in whitelist" % pathname
                 return
         liststore.append([_('Folder'), pathname])
         pathnames.append(['folder', pathname])
         options.set_custom_paths(pathnames)
Пример #14
0
    def __languages_page(self):
        """Return widget containing the languages page"""

        def preserve_toggled_cb(cell, path, liststore):
            """Callback for toggling the 'preserve' column"""
            __iter = liststore.get_iter_from_string(path)
            value = not liststore.get_value(__iter, 0)
            liststore.set(__iter, 0, value)
            langid = liststore[path][1]
            options.set_language(langid, value)

        vbox = gtk.VBox()

        notice = gtk.Label(
            _("All languages will be deleted except those checked."))
        vbox.pack_start(notice)

        # populate data
        liststore = gtk.ListStore('gboolean', str, str)
        for lang in Unix.locales.iterate_languages():
            preserve = options.get_language(lang)
            native = Unix.locales.native_name(lang)
            liststore.append([preserve, lang, native])

        # create treeview
        treeview = gtk.TreeView(liststore)

        # create column views
        self.renderer0 = gtk.CellRendererToggle()
        self.renderer0.set_property('activatable', True)
        self.renderer0.connect('toggled', preserve_toggled_cb, liststore)
        self.column0 = gtk.TreeViewColumn(
            _("Preserve"), self.renderer0, active=0)
        treeview.append_column(self.column0)

        self.renderer1 = gtk.CellRendererText()
        self.column1 = gtk.TreeViewColumn(_("Code"), self.renderer1, text=1)
        treeview.append_column(self.column1)

        self.renderer2 = gtk.CellRendererText()
        self.column2 = gtk.TreeViewColumn(_("Name"), self.renderer2, text=2)
        treeview.append_column(self.column2)
        treeview.set_search_column(2)

        # finish
        swindow = gtk.ScrolledWindow()
        swindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        swindow.set_size_request(300, 200)
        swindow.add(treeview)
        vbox.pack_start(swindow, False)
        return vbox
Пример #15
0
    def __init__(self):
        Cleaner.__init__(self)
        self.options = {}
        self.add_option("cache", _("Cache"), _("Delete the cache"))
        self.add_option("recent_documents", _("Most recently used"), _("Delete the list of recently used documents"))
        self.id = "openofficeorg"
        self.name = "OpenOffice.org"
        self.description = _("Office suite")

        # reference: http://katana.oooninja.com/w/editions_of_openoffice.org
        if "posix" == os.name:
            self.prefixes = ["~/.ooo-2.0", "~/.openoffice.org2", "~/.openoffice.org2.0", "~/.openoffice.org/3"]
            self.prefixes += ["~/.ooo-dev3"]
        if "nt" == os.name:
            self.prefixes = ["$APPDATA\\OpenOffice.org\\3", "$APPDATA\\OpenOffice.org2"]
Пример #16
0
 def add_whitelist_folder_cb(button):
     """Callback for adding a folder"""
     title = _("Choose a folder")
     pathname = GuiBasic.browse_folder(self.parent,
                                       title,
                                       multiple=False,
                                       stock_button=gtk.STOCK_ADD)
     if pathname:
         for this_pathname in pathnames:
             if pathname == this_pathname[1]:
                 print "warning: '%s' already exists in whitelist" % pathname
                 return
         liststore.append([_('Folder'), pathname])
         pathnames.append(['folder', pathname])
         options.set_whitelist_paths(pathnames)
Пример #17
0
    def create_toolbar(self):
        """Create the toolbar"""
        toolbar = gtk.Toolbar()

        # create the preview button
        preview_icon = gtk.Image()
        preview_icon.set_from_stock(
            gtk.STOCK_FIND, gtk.ICON_SIZE_LARGE_TOOLBAR)
        # TRANSLATORS: This is the preview button on the main window.  It
        # previews changes.
        preview_button = gtk.ToolButton(
            icon_widget=preview_icon, label=_p('button', "Preview"))
        preview_button.connect(
            "clicked", lambda *dummy: self.preview_or_run_operations(False))
        toolbar.insert(preview_button, -1)
        preview_button.set_tooltip_text(
            _("Preview files in the selected operations (without deleting any files)"))
        preview_button.set_is_important(True)

        # create the delete button
        icon = gtk.Image()
        icon.set_from_stock(gtk.STOCK_DELETE, gtk.ICON_SIZE_LARGE_TOOLBAR)
        # TRANSLATORS: This is the clean button on the main window.
        # It makes permanent changes: usually deleting files, sometimes
        # altering them.
        run_button = gtk.ToolButton(
            icon_widget=icon, label=_p("button", "Clean"))
        run_button.connect("clicked", self.run_operations)
        toolbar.insert(run_button, -1)
        run_button.set_tooltip_text(
            _("Clean files in the selected operations"))
        run_button.set_is_important(True)
		
		# create the stop 
        icon = gtk.Image()
        icon.set_from_stock(gtk.STOCK_STOP, gtk.ICON_SIZE_LARGE_TOOLBAR)
        # TRANSLATORS: This is the clean button on the main window.
        # It makes permanent changes: usually deleting files, sometimes
        # altering them.
        run_button = gtk.ToolButton(
            icon_widget=icon, label=_p("button", "Stop!"))
        run_button.connect("clicked", self.run_operations_stop)  
        toolbar.insert(run_button, -1)
        run_button.set_tooltip_text(
            _("STOP the running operations"))
        run_button.set_is_important(True)

        return toolbar
Пример #18
0
def apt_autoremove():
    """Run 'apt-get autoremove' and return the size (un-rounded, in bytes)
        of freed space"""

    if not FileUtilities.exe_exists('apt-get'):
        raise RuntimeError(_('Executable not found: %s') % 'apt-get')

    args = ['apt-get', '--yes', 'autoremove']

    process = subprocess.Popen(args,
                               stderr=subprocess.STDOUT,
                               stdout=subprocess.PIPE)

    total_bytes = 0

    while True:
        line = process.stdout.readline().replace("\n", "")
        if line.startswith('E: '):
            raise RuntimeError(line)
        # After this operation, 74.7MB disk space will be freed.
        match = re.search(r", ([0-9.]+[a-zA-Z]{2}) disk space will be freed",
                          line)
        if match:
            pkg_bytes_str = match.groups(0)[0]
            pkg_bytes = FileUtilities.human_to_bytes(pkg_bytes_str.upper())
            total_bytes += pkg_bytes
        if "" == line and process.poll() != None:
            break

    return total_bytes
Пример #19
0
    def execute(self, really_delete):
        """Execute the Windows registry cleaner"""
        if 'nt' != os.name:
            raise StopIteration
        _str = None  # string representation
        ret = None  # return value meaning 'deleted' or 'delete-able'
        if self.valuename:
            _str = '%s<%s>' % (self.keyname, self.valuename)
            ret = Windows.delete_registry_value(self.keyname,
                                                self.valuename, really_delete)
        else:
            ret = Windows.delete_registry_key(self.keyname, really_delete)
            _str = self.keyname
        if not ret:
            # Nothing to delete or nothing was deleted.  This return
            # makes the auto-hide feature work nicely.
            raise StopIteration

        ret = {
            'label': _('Delete registry key'),
            'n_deleted': 0,
            'n_special': 1,
            'path': _str,
            'size': 0}

        yield ret
Пример #20
0
    def run_deep_scan(self):
        """Run deep scans"""
        print "debug: deepscans=", self.deepscans
        # TRANSLATORS: The "deep scan" feature searches over broad
        # areas of the file system such as the user's whole home directory
        # or all the system executables.
        self.ui.update_progress_bar(_("Please wait.  Running deep scan."))
        yield True  # allow GTK to update the screen
        ds = DeepScan.DeepScan()
        for (path, dsdict) in self.deepscans.iteritems():
            print "debug: deepscan path=", path
            print "debug: deepscan dict=", dsdict
            for dsdict2 in dsdict:
                ds.add_search(path, dsdict2["regex"])

        for path in ds.scan():
            if True == path:
                yield True
                continue
            # fixme: support non-delete commands
            import Command

            cmd = Command.Delete(path)
            for ret in self.execute(cmd):
                yield True
Пример #21
0
def create_wipe_cleaner(path):
    """Wipe free disk space of arbitrary paths (used in GUI)"""
    cleaner = Cleaner()
    cleaner.add_option(
        option_id='free_disk_space', name='', description='')
    cleaner.name = ''

    # create a temporary cleaner object
    display = _("Overwrite free disk space %s") % path

    def wipe_path_func():
        for ret in FileUtilities.wipe_path(path, idle=True):
            yield ret
        yield 0

    import Action

    class CustomWipeAction(Action.ActionProvider):
        action_key = '__customwipeaction'

        def get_commands(self):
            yield Command.Function(None, wipe_path_func, display)
    provider = CustomWipeAction(None)
    cleaner.add_action('free_disk_space', provider)
    return cleaner
Пример #22
0
def create_simple_cleaner(paths):
    """Shred arbitrary files (used in CLI and GUI)"""
    cleaner = Cleaner()
    cleaner.add_option(option_id='files', name='', description='')
    cleaner.name = _("System")  # shows up in progress bar

    import Action

    class CustomFileAction(Action.ActionProvider):
        action_key = '__customfileaction'

        def get_commands(self):
            for path in paths:
                if not isinstance(path, (str, unicode)):
                    raise RuntimeError(
                        'expected path as string but got %s' % str(path))
                if os.path.isdir(path):
                    for child in children_in_directory(path, True):
                        yield Command.Shred(child)
                    yield Command.Shred(path)
                else:
                    yield Command.Shred(path)
    provider = CustomFileAction(None)
    cleaner.add_action('files', provider)
    return cleaner
Пример #23
0
 def add_section(self, cleaner_id, name):
     """Add a section (cleaners)"""
     self.cleaner_ids.append(cleaner_id)
     self.cleaners[cleaner_id] = Cleaner.Cleaner()
     self.cleaners[cleaner_id].id = cleaner_id
     self.cleaners[cleaner_id].name = name
     self.cleaners[cleaner_id].description = _('Imported from winapp2.ini')
Пример #24
0
def update_winapp2(url, hash_expected, append_text, cb_success):
    """Download latest winapp2.ini file.  Hash is sha512 or None to disable checks"""
    # first, determine whether an update is necessary
    from Common import personal_cleaners_dir
    fn = os.path.join(personal_cleaners_dir, 'winapp2.ini')
    delete_current = False
    if os.path.exists(fn):
        f = open(fn, 'r')
        hash_current = hashlib.sha512(f.read()).hexdigest()
        if not hash_expected or hash_current == hash_expected:
            # update is same as current
            return
        f.close()
        delete_current = True
    # download update
    opener = urllib2.build_opener()
    opener.addheaders = [('User-Agent', user_agent())]
    doc = opener.open(url).read()
    # verify hash
    hash_actual = hashlib.sha512(doc).hexdigest()
    if hash_expected and not hash_actual == hash_expected:
        raise RuntimeError("hash for %s actually %s instead of %s" %
                          (url, hash_actual, hash_expected))
    # delete current
    if delete_current:
        from FileUtilities import delete
        delete(fn, True)
    # write file
    if not os.path.exists(personal_cleaners_dir):
        os.mkdir(personal_cleaners_dir)
    f = open(fn, 'w')
    f.write(doc)
    append_text(_('New winapp2.ini was downloaded.'))
    cb_success()
Пример #25
0
    def execute(self, really_delete):
        """Execute the Windows registry cleaner"""
        if 'nt' != os.name:
            raise StopIteration
        _str = None  # string representation
        ret = None  # return value meaning 'deleted' or 'delete-able'
        if self.valuename:
            _str = '%s<%s>' % (self.keyname, self.valuename)
            ret = Windows.delete_registry_value(self.keyname, self.valuename,
                                                really_delete)
        else:
            ret = Windows.delete_registry_key(self.keyname, really_delete)
            _str = self.keyname
        if not ret:
            # Nothing to delete or nothing was deleted.  This return
            # makes the auto-hide feature work nicely.
            raise StopIteration

        ret = {
            'label': _('Delete registry key'),
            'n_deleted': 0,
            'n_special': 1,
            'path': _str,
            'size': 0
        }

        yield ret
Пример #26
0
 def handle_cleaner_option_label(self, label):
     """<label> element under <option>"""
     self.option_name = _(getText(label.childNodes))
     translate = label.getAttribute('translate')
     translators = label.getAttribute('translators')
     if not translate or boolstr_to_bool(translate):
         self.xlate_cb(self.option_name, translators)
Пример #27
0
def run_cleaner_cmd(cmd,
                    args,
                    freed_space_regex=r'[\d.]+[kMGTE]?B?',
                    error_line_regexes=None):
    """Runs a specified command and returns how much space was (reportedly) freed.
    The subprocess shouldn't need any user input and the user should have the
    necessary rights.
    freed_space_regex gets applied to every output line, if the re matches,
    add values captured by the single group in the regex"""
    if not FileUtilities.exe_exists(cmd):
        raise RuntimeError(_('Executable not found: %s') % cmd)
    freed_space_regex = re.compile(freed_space_regex)
    error_line_regexes = [
        re.compile(regex) for regex in error_line_regexes or []
    ]

    output = subprocess.check_output([cmd] + args,
                                     stderr=subprocess.STDOUT,
                                     universal_newlines=True,
                                     env={'LC_ALL': 'C'})

    freed_space = 0
    for line in output.split('\n'):
        m = freed_space_regex.match(line)
        if m is not None:
            freed_space += FileUtilities.human_to_bytes(m.group(1))
        for error_re in error_line_regexes:
            if error_re.search(line):
                raise RuntimeError('Invalid output from %s: %s' % (cmd, line))

    return freed_space
Пример #28
0
 def add_section(self, cleaner_id, name):
     """Add a section (cleaners)"""
     self.cleaner_ids.append(cleaner_id)
     self.cleaners[cleaner_id] = Cleaner.Cleaner()
     self.cleaners[cleaner_id].id = cleaner_id
     self.cleaners[cleaner_id].name = name
     self.cleaners[cleaner_id].description = _('Imported from winapp2.ini')
Пример #29
0
def update_winapp2(url, hash_expected, append_text, cb_success):
    """Download latest winapp2.ini file.  Hash is sha512 or None to disable checks"""
    # first, determine whether an update is necessary
    from Common import personal_cleaners_dir
    fn = os.path.join(personal_cleaners_dir, 'winapp2.ini')
    delete_current = False
    if os.path.exists(fn):
        f = open(fn, 'r')
        hash_current = hashlib.sha512(f.read()).hexdigest()
        if not hash_expected or hash_current == hash_expected:
            # update is same as current
            return
        f.close()
        delete_current = True
    # download update
    opener = urllib2.build_opener()
    opener.addheaders = [('User-Agent', user_agent())]
    doc = opener.open(url).read()
    # verify hash
    hash_actual = hashlib.sha512(doc).hexdigest()
    if hash_expected and not hash_actual == hash_expected:
        raise RuntimeError("hash for %s actually %s instead of %s" %
                           (url, hash_actual, hash_expected))
    # delete current
    if delete_current:
        from FileUtilities import delete
        delete(fn, True)
    # write file
    if not os.path.exists(personal_cleaners_dir):
        os.mkdir(personal_cleaners_dir)
    f = open(fn, 'w')
    f.write(doc)
    append_text(_('New winapp2.ini was downloaded.'))
    cb_success()
Пример #30
0
    def preview_or_run_operations(self, really_delete, operations=None):
        """Preview operations or run operations (delete files)"""
		
        assert(isinstance(really_delete, bool))
        import Worker
        self.start_time = None
        if None == operations:
            operations = {}
            for operation in self.get_selected_operations():
                operations[operation] = self.get_operation_options(operation)
        assert(isinstance(operations, dict))
        if 0 == len(operations):
            GuiBasic.message_dialog(self.window,
                                    _("You must select an operation"),
                                    gtk.MESSAGE_WARNING, gtk.BUTTONS_OK)
            return
        try:
            self.set_sensitive(True)
            self.textbuffer.set_text("")
            self.progressbar.show()
            print "STOP NOW"
            print self,stop_now
            self.worker = Worker.Worker(self, really_delete, operations, self.stop_now)
        except:
            traceback.print_exc()
            err = str(sys.exc_info()[1])
            self.append_text(err + "\n", 'error')
        else:
            self.start_time = time.time()
            worker = self.worker.run()
            gobject.idle_add(worker.next)
Пример #31
0
 def handle_cleaner_option_label(self, label):
     """<label> element under <option>"""
     self.option_name = _(getText(label.childNodes))
     translate = label.getAttribute('translate')
     translators = label.getAttribute('translators')
     if not translate or boolstr_to_bool(translate):
         self.xlate_cb(self.option_name, translators)
Пример #32
0
 def set_cleaner(self, path, model, parent_window, value=None):
     """Activate or deactive option of cleaner."""
     if None == value:
         # if not value given, toggle current value
         value = not model[path][1]
     assert(type(value) is types.BooleanType)
     assert(type(model) is gtk.TreeStore)
     cleaner_id = None
     i = path
     if type(i) is str:
         # type is either str or gtk.TreeIter
         i = model.get_iter(path)
     parent = model.iter_parent(i)
     if None != parent:
         # this is an option (child), not a cleaner (parent)
         cleaner_id = model[parent][2]
         option_id = model[path][2]
     if cleaner_id and value:
         # when toggling an option, present any warnings
         warning = backends[cleaner_id].get_warning(option_id)
         # TRANSLATORS: %(cleaner) may be Firefox, System, etc.
         # %(option) may be cache, logs, cookies, etc.
         # %(warning) may be 'This option is really slow'
         msg = _("Warning regarding %(cleaner)s - %(option)s:\n\n%(warning)s") % \
             {'cleaner': model[parent][0],
              'option': model[path][0],
              'warning': warning}
         if warning:
             resp = GuiBasic.message_dialog(parent_window,
                                            msg,
                                            gtk.MESSAGE_WARNING, gtk.BUTTONS_OK_CANCEL)
             if gtk.RESPONSE_OK != resp:
                 # user cancelled, so don't toggle option
                 return
     model[path][1] = value
Пример #33
0
def create_simple_cleaner(paths):
    """Shred arbitrary files (used in CLI and GUI)"""
    cleaner = Cleaner()
    cleaner.add_option(option_id='files', name='', description='')
    cleaner.name = _("System")  # shows up in progress bar

    import Action

    class CustomFileAction(Action.ActionProvider):
        action_key = '__customfileaction'

        def get_commands(self):
            for path in paths:
                if not isinstance(path, (str, unicode)):
                    raise RuntimeError(
                        'expected path as string but got %s' % str(path))
                if os.path.isdir(path):
                    for child in children_in_directory(path, True):
                        yield Command.Shred(child)
                    yield Command.Shred(path)
                else:
                    yield Command.Shred(path)
    provider = CustomFileAction(None)
    cleaner.add_action('files', provider)
    return cleaner
Пример #34
0
def create_wipe_cleaner(path):
    """Wipe free disk space of arbitrary paths (used in GUI)"""
    cleaner = Cleaner()
    cleaner.add_option(
        option_id='free_disk_space', name='', description='')
    cleaner.name = ''

    # create a temporary cleaner object
    display = _("Overwrite free disk space %s") % path

    def wipe_path_func():
        for ret in FileUtilities.wipe_path(path, idle=True):
            yield ret
        yield 0

    import Action

    class CustomWipeAction(Action.ActionProvider):
        action_key = '__customwipeaction'

        def get_commands(self):
            yield Command.Function(None, wipe_path_func, display)
    provider = CustomWipeAction(None)
    cleaner.add_action('free_disk_space', provider)
    return cleaner
Пример #35
0
 def __init__(self, uac=True, shred_paths=None):
     if uac and 'nt' == os.name and Windows.elevate_privileges():
         # privileges escalated in other process
         sys.exit(0)
     import RecognizeCleanerML
     RecognizeCleanerML.RecognizeCleanerML()
     register_cleaners()
     self.create_window()
     gobject.threads_init()
     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 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, e:
             print e
             print dir(e)
             self.append_text(
                 _("Error loading the SQLite module: the antivirus software may be blocking it."), 'error')
Пример #36
0
 def diagnostic_dialog(self, parent):
     """Show diagnostic information"""
     dialog = gtk.Dialog(_("System information"), parent)
     dialog.resize(600, 400)
     txtbuffer = gtk.TextBuffer()
     import Diagnostic
     txt = Diagnostic.diagnostic_info()
     txtbuffer.set_text(txt)
     textview = gtk.TextView(txtbuffer)
     textview.set_editable(False)
     swindow = gtk.ScrolledWindow()
     swindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
     swindow.add_with_viewport(textview)
     dialog.vbox.pack_start(swindow)
     dialog.add_buttons(
         gtk.STOCK_COPY, 100, gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
     dialog.show_all()
     while True:
         rc = dialog.run()
         if 100 == rc:
             clipboard = gtk.clipboard_get()
             clipboard.set_text(txt)
         else:
             break
     dialog.hide()
Пример #37
0
def apt_autoremove():
    """Run 'apt-get autoremove' and return the size (un-rounded, in bytes)
        of freed space"""

    if not FileUtilities.exe_exists('apt-get'):
        raise RuntimeError(_('Executable not found: %s') % 'apt-get')

    args = ['apt-get', '--yes', 'autoremove']

    process = subprocess.Popen(args,
                               stderr=subprocess.STDOUT, stdout=subprocess.PIPE)

    total_bytes = 0

    while True:
        line = process.stdout.readline().replace("\n", "")
        if line.startswith('E: '):
            raise RuntimeError(line)
        # After this operation, 74.7MB disk space will be freed.
        match = re.search(
            r", ([0-9.]+[a-zA-Z]{2}) disk space will be freed", line)
        if match:
            pkg_bytes_str = match.groups(0)[0]
            pkg_bytes = FileUtilities.human_to_bytes(pkg_bytes_str.upper())
            total_bytes += pkg_bytes
        if "" == line and process.poll() != None:
            break

    return total_bytes
Пример #38
0
def apt_autoclean():
    """Run 'apt-get autoclean' and return the size (un-rounded, in bytes)
        of freed space"""

    if not FileUtilities.exe_exists('apt-get'):
        raise RuntimeError(_('Executable not found: %s') % 'apt-get')

    args = ['apt-get', 'autoclean']

    process = subprocess.Popen(args,
                               stderr=subprocess.STDOUT, stdout=subprocess.PIPE)

    total_bytes = 0

    while True:
        line = process.stdout.readline().replace("\n", "")
        if line.startswith('E: '):
            raise RuntimeError(line)
        # Del cups-common 1.3.9-17ubuntu3 [1165kB]
        match = re.search("^Del .*\[([0-9.]+[a-zA-Z]{2})\]", line)
        if match:
            pkg_bytes_str = match.groups(0)[0]
            pkg_bytes = FileUtilities.human_to_bytes(pkg_bytes_str.upper())
            total_bytes += pkg_bytes
        if "" == line and process.poll() != None:
            break

    return total_bytes
Пример #39
0
def apt_autoclean():
    """Run 'apt-get autoclean' and return the size (un-rounded, in bytes)
        of freed space"""

    if not FileUtilities.exe_exists('apt-get'):
        raise RuntimeError(_('Executable not found: %s') % 'apt-get')

    args = ['apt-get', 'autoclean']

    process = subprocess.Popen(args,
                               stderr=subprocess.STDOUT,
                               stdout=subprocess.PIPE)

    total_bytes = 0

    while True:
        line = process.stdout.readline().replace("\n", "")
        if line.startswith('E: '):
            raise RuntimeError(line)
        # Del cups-common 1.3.9-17ubuntu3 [1165kB]
        match = re.search("^Del .*\[([0-9.]+[a-zA-Z]{2})\]", line)
        if match:
            pkg_bytes_str = match.groups(0)[0]
            pkg_bytes = FileUtilities.human_to_bytes(pkg_bytes_str.upper())
            total_bytes += pkg_bytes
        if "" == line and process.poll() != None:
            break

    return total_bytes
Пример #40
0
    def get_commands(self, option_id):
        # paths for which to run expand_glob_join
        egj = []
        if 'recent_documents' == option_id:
            egj.append(
                "user/registry/data/org/openoffice/Office/Histories.xcu")
            egj.append(
                "user/registry/cache/org.openoffice.Office.Histories.dat")

        if 'recent_documents' == option_id and not 'cache' == option_id:
            egj.append("user/registry/cache/org.openoffice.Office.Common.dat")

        for egj_ in egj:
            for prefix in self.prefixes:
                for path in FileUtilities.expand_glob_join(prefix, egj_):
                    if 'nt' == os.name:
                        path = os.path.normpath(path)
                    if os.path.lexists(path):
                        yield Command.Delete(path)

        if 'cache' == option_id:
            dirs = []
            for prefix in self.prefixes:
                dirs += FileUtilities.expand_glob_join(
                    prefix, "user/registry/cache/")
            for dirname in dirs:
                if 'nt' == os.name:
                    dirname = os.path.normpath(dirname)
                for filename in children_in_directory(dirname, False):
                    yield Command.Delete(filename)

        if 'recent_documents' == option_id:
            for prefix in self.prefixes:
                for path in FileUtilities.expand_glob_join(prefix, "user/registry/data/org/openoffice/Office/Common.xcu"):
                    if os.path.lexists(path):
                        yield Command.Function(path,
                                               Special.delete_ooo_history,
                                               _('Delete the usage history'))
                # ~/.openoffice.org/3/user/registrymodifications.xcu
                #       Apache OpenOffice.org 3.4.1 from openoffice.org on Ubuntu 13.04
                # %AppData%\OpenOffice.org\3\user\registrymodifications.xcu
                # Apache OpenOffice.org 3.4.1 from openoffice.org on Windows XP
                for path in FileUtilities.expand_glob_join(prefix, "user/registrymodifications.xcu"):
                    if os.path.lexists(path):
                        yield Command.Function(path,
                                               Special.delete_office_registrymodifications,
                                               _('Delete the usage history'))
Пример #41
0
    def cb_shred_file(self, action):
        """Callback for shredding a file or folder"""

        # get list of files
        if "ShredFiles" == action.get_name():
            paths = GuiBasic.browse_files(self.window, _("Choose files to shred"))
        elif "ShredFolders" == action.get_name():
            paths = GuiBasic.browse_folder(
                self.window, _("Choose folder to shred"), multiple=True, stock_button=gtk.STOCK_DELETE
            )
        else:
            raise RuntimeError("Unexpected kind in cb_shred_file")

        if not paths:
            return

        self.shred_paths(paths)
Пример #42
0
    def __init__(self):
        Cleaner.__init__(self)
        self.options = {}
        self.add_option('cache', _('Cache'), _('Delete the cache'))
        self.add_option('recent_documents', _('Most recently used'),
                        _("Delete the list of recently used documents"))

        # reference: http://katana.oooninja.com/w/editions_of_openoffice.org
        if 'posix' == os.name:
            self.prefixes = [
                "~/.ooo-2.0", "~/.openoffice.org2", "~/.openoffice.org2.0",
                "~/.openoffice.org/3"
            ]
            self.prefixes += ["~/.ooo-dev3"]
        if 'nt' == os.name:
            self.prefixes = [
                "$APPDATA\\OpenOffice.org\\3", "$APPDATA\\OpenOffice.org2"
            ]
Пример #43
0
 def add_drive_cb(button):
     """Callback for adding a drive"""
     title = _("Choose a folder")
     pathname = GuiBasic.browse_folder(self.parent, title,
                                       multiple=False, stock_button=gtk.STOCK_ADD)
     if pathname:
         liststore.append([pathname])
         pathnames.append(pathname)
         options.set_list('shred_drives', pathnames)
Пример #44
0
    def cb_shred_file(self, action):
        """Callback for shredding a file or folder"""

        # get list of files
        if 'ShredFiles' == action.get_name():
            paths = GuiBasic.browse_files(self.window,
                                          _("Choose files to shred"))
        elif 'ShredFolders' == action.get_name():
            paths = GuiBasic.browse_folder(self.window,
                                           _("Choose folder to shred"),
                                           multiple=True,
                                           stock_button=gtk.STOCK_DELETE)
        else:
            raise RuntimeError("Unexpected kind in cb_shred_file")

        if not paths:
            return

        self.shred_paths(paths)
Пример #45
0
 def get_commands(self):
     for path in self.get_paths():
         yield Command.Function(
             path,
             FileUtilities.vacuum_sqlite3,
             # TRANSLATORS: Vacuum is a verb.  The term is jargon
             # from the SQLite database.  Microsoft Access uses
             # the term 'Compact Database' (which you may translate
             # instead).  Another synonym is 'defragment.'
             _('Vacuum'))
Пример #46
0
 def print_exception(self, operation):
     """Display exception"""
     # TRANSLATORS: This indicates an error.  The special keyword
     # %(operation)s will be replaced by 'firefox' or 'opera' or
     # some other cleaner ID.  The special keyword %(msg)s will be
     # replaced by a message such as 'Permission denied.'
     err = _("Exception while running operation '%(operation)s': '%(msg)s'") \
         % {'operation': operation, 'msg': str(sys.exc_info()[1])}
     logger = logging.getLogger(__name__)
     logger.error(err, exc_info=True)
     self.total_errors += 1
Пример #47
0
def whitelist(path):
    """Return information that this file was whitelisted"""
    ret = {
        # TRANSLATORS: This is the label in the log indicating was
        # skipped because it matches the whitelist
        'label': _('Skip'),
        'n_deleted': 0,
        'n_special': 0,
        'path': path,
        'size': 0}
    return ret
Пример #48
0
    def get_commands(self, option_id):
        if 'recent_documents' == option_id:
            for prefix in self.prefixes:
                for path in FileUtilities.expand_glob_join(prefix, "user/registry/data/org/openoffice/Office/Histories.xcu"):
                    if os.path.lexists(path):
                        yield Command.Delete(path)
                for path in FileUtilities.expand_glob_join(prefix, "user/registry/cache/org.openoffice.Office.Histories.dat"):
                    if os.path.lexists(path):
                        yield Command.Delete(path)

        if 'recent_documents' == option_id and not 'cache' == option_id:
            for prefix in self.prefixes:
                for path in FileUtilities.expand_glob_join(prefix, "user/registry/cache/org.openoffice.Office.Common.dat"):
                    if os.path.lexists(path):
                        yield Command.Delete(path)

        if 'cache' == option_id:
            dirs = []
            for prefix in self.prefixes:
                dirs += FileUtilities.expand_glob_join(
                    prefix, "user/registry/cache/")
            for dirname in dirs:
                for filename in children_in_directory(dirname, False):
                    yield Command.Delete(filename)

        if 'recent_documents' == option_id:
            for prefix in self.prefixes:
                for path in FileUtilities.expand_glob_join(prefix, "user/registry/data/org/openoffice/Office/Common.xcu"):
                    if os.path.lexists(path):
                        yield Command.Function(path,
                                               Special.delete_ooo_history,
                                               _('Delete the usage history'))
                # ~/.openoffice.org/3/user/registrymodifications.xcu
                #       Apache OpenOffice.org 3.4.1 from openoffice.org on Ubuntu 13.04
                # %AppData%\OpenOffice.org\3\user\registrymodifications.xcu
                # Apache OpenOffice.org 3.4.1 from openoffice.org on Windows XP
                for path in FileUtilities.expand_glob_join(prefix, "user/registrymodifications.xcu"):
                    if os.path.lexists(path):
                        yield Command.Function(path,
                                               Special.delete_office_registrymodifications,
                                               _('Delete the usage history'))
Пример #49
0
    def context_menu_event(self, treeview, event):
        """When user right clicks on the tree view"""
        if event.button != 3:
            return False
        pathinfo = treeview.get_path_at_pos(int(event.x), int(event.y))
        if None == pathinfo:
            return False
        path, col, cellx, celly = pathinfo
        treeview.grab_focus()
        treeview.set_cursor(path, col, 0)
        # context menu applies only to children, not parents
        if 2 != len(path):
            return False
        # find the seleted option
        model = treeview.get_model()
        option_id = model[path][2]
        cleaner_id = model[path[0]][2]
        cleaner_name = model[path[0]][0]
        # make a menu
        menu = gtk.Menu()
        # TRANSLATORS: this is the context menu
        preview_item = gtk.MenuItem(_("Preview"))
        preview_item.connect('activate', self.cb_run_option,
                             False, cleaner_id, option_id)
        menu.append(preview_item)
        # TRANSLATORS: this is the context menu
        clean_item = gtk.MenuItem(_("Clean"))
        clean_item.connect('activate', self.cb_run_option,
                           True, cleaner_id, option_id)
        menu.append(clean_item)

		# TRANSLATORS: this is the context menu
        stop_item = gtk.MenuItem(_("Stop"))
        stop_item.connect('activate', self.run_operations_stop)
        menu.append(stop_item)

        # show the context menu
        menu.attach_to_widget(treeview, menu.destroy)
        menu.show_all()
        menu.popup(None, None, None, event.button, event.time)
        return True
Пример #50
0
    def clean_operation(self, operation):
        """Perform a single cleaning operation"""
        operation_options = self.operations[operation]
        assert (isinstance(operation_options, list))
        logger = logging.getLogger(__name__)
        logger.debug("clean_operation('%s'), options = '%s'" %
                     (operation, operation_options))

        if not operation_options:
            raise StopIteration

        if self.really_delete and backends[operation].is_running():
            # TRANSLATORS: %s expands to a name such as 'Firefox' or 'System'.
            err = _("%s cannot be cleaned because it is currently running.  Close it, and try again.") \
                % backends[operation].get_name()
            self.ui.append_text(err + "\n", 'error')
            self.total_errors += 1
            return
        import time
        self.yield_time = time.time()

        total_size = 0
        for option_id in operation_options:
            self.size = 0
            assert (isinstance(option_id, (str, unicode)))
            # normal scan
            for cmd in backends[operation].get_commands(option_id):
                for ret in self.execute(cmd):
                    if True == ret:
                        # Return control to PyGTK idle loop to keep
                        # it responding allow the user to abort
                        self.yield_time = time.time()
                        yield True
                if time.time() - self.yield_time > 0.25:
                    if self.really_delete:
                        self.ui.update_total_size(self.total_bytes)
                    yield True
                    self.yield_time = time.time()

            self.ui.update_item_size(operation, option_id, self.size)
            total_size += self.size

            # deep scan
            for ds in backends[operation].get_deep_scan(option_id):
                if '' == ds['path']:
                    ds['path'] = os.path.expanduser('~')
                if 'delete' != ds['command']:
                    raise NotImplementedError(
                        'Deep scan only supports deleting now')
                if not self.deepscans.has_key(ds['path']):
                    self.deepscans[ds['path']] = []
                self.deepscans[ds['path']].append(ds)
        self.ui.update_item_size(operation, -1, total_size)
Пример #51
0
    def run_operations(self, my_operations):
        """Run a set of operations (general, memory, free disk space)"""
        count = 0
        for operation in my_operations:
            self.ui.update_progress_bar(1.0 * count / len(my_operations))
            name = backends[operation].get_name()
            if self.really_delete:
                # TRANSLATORS: %s is replaced with Firefox, System, etc.
                msg = _("Please wait.  Cleaning %s.") % name
            else:
                # TRANSLATORS: %s is replaced with Firefox, System, etc.
                msg = _("Please wait.  Previewing %s.") % name
            self.ui.update_progress_bar(msg)
            yield True  # show the progress bar message now
            try:
                for dummy in self.clean_operation(operation):
                    yield True
            except:
                self.print_exception(operation)

            count += 1
Пример #52
0
 def print_exception(self, operation):
     """Display exception"""
     # TRANSLATORS: This indicates an error.  The special keyword
     # %(operation)s will be replaced by 'firefox' or 'opera' or
     # some other cleaner ID.  The special keyword %(msg)s will be
     # replaced by a message such as 'Permission denied.'
     err = _("Exception while running operation '%(operation)s': '%(msg)s'") \
         % {'operation': operation, 'msg': str(sys.exc_info()[1])}
     print err
     traceback.print_exc()
     self.ui.append_text(err + "\n", 'error')
     self.total_errors += 1
Пример #53
0
 def run_delayed_op(self, operation, option_id):
     """Run one delayed operation"""
     self.ui.update_progress_bar(0.0)
     if 'free_disk_space' == option_id:
         # TRANSLATORS: 'free' means 'unallocated'
         msg = _("Please wait.  Wiping free disk space.")
     elif 'memory' == option_id:
         msg = _("Please wait.  Cleaning %s.") % _("Memory")
     else:
         raise RuntimeError("Unexpected option_id in delayed ops")
     self.ui.update_progress_bar(msg)
     for cmd in backends[operation].get_commands(option_id):
         old_phase = None
         for ret in self.execute(cmd):
             if isinstance(ret, tuple):
                 # Display progress (for free disk space)
                 phase = ret[
                     0]  # 1=wipe free disk space, 2=wipe inodes, 3=clean up inodes files
                 percent_done = ret[1]
                 eta_seconds = ret[2]
                 self.ui.update_progress_bar(percent_done)
                 if phase == 2:
                     msg = _('Please wait. Wiping file system metadata.')
                 elif phase == 3:
                     msg = _(
                         'Please wait. Cleaning up after wiping file system metadata.'
                     )
                 if isinstance(eta_seconds, int):
                     eta_mins = math.ceil(eta_seconds / 60)
                     msg2 = ungettext("About %d minute remaining.",
                                      "About %d minutes remaining.", eta_mins) \
                         % eta_mins
                     self.ui.update_progress_bar(msg + ' ' + msg2)
                 else:
                     self.ui.update_progress_bar(msg)
             if True == ret or isinstance(ret, tuple):
                 # Return control to PyGTK idle loop to keep
                 # it responding and allow the user to abort.
                 yield True
Пример #54
0
    def cb_wipe_free_space(self, action):
        """callback to wipe free space in arbitrary folder"""
        path = GuiBasic.browse_folder(self.window,
                                      _("Choose a folder"),
                                      multiple=False, stock_button=gtk.STOCK_OK)
        if not path:
            # user cancelled
            return

        backends['_gui'] = Cleaner.create_wipe_cleaner(path)

        # execute
        operations = {'_gui': ['free_disk_space']}
        self.preview_or_run_operations(True, operations)
Пример #55
0
def yum_clean():
    """Run 'yum clean all' and return size in bytes recovered"""
    if os.path.exists('/var/run/yum.pid'):
        msg = _(
            "%s cannot be cleaned because it is currently running.  Close it, and try again."
        ) % "Yum"
        raise RuntimeError(msg)

    old_size = FileUtilities.getsizedir('/var/cache/yum')
    args = ['--enablerepo=*', 'clean', 'all']
    invalid = ['You need to be root', 'Cannot remove rpmdb file']
    run_cleaner_cmd('yum', args, '^unused regex$', invalid)
    new_size = FileUtilities.getsizedir('/var/cache/yum')
    return old_size - new_size
Пример #56
0
 def check_online_updates(self):
     """Check for software updates in background"""
     import Update
     try:
         updates = Update.check_updates(options.get('check_beta'),
                                        options.get('update_winapp2'),
                                        self.append_text,
                                        lambda: gobject.idle_add(self.cb_refresh_operations))
         if updates:
             gobject.idle_add(
                 lambda: Update.update_dialog(self.window, updates))
     except:
         traceback.print_exc()
         self.append_text(
             _("Error when checking for updates: ") + str(sys.exc_info()[1]), 'error')