1
0
mirror of https://github.com/arsenetar/dupeguru.git synced 2025-03-10 05:34:36 +00:00

[#20 state:port] Added default excludes to Directories.

--HG--
extra : convert_revision : svn%3Ac306627e-7827-47d3-bdf0-9a457c9553a1/trunk%4028
This commit is contained in:
hsoft 2009-06-09 15:35:17 +00:00
parent b7e391cafb
commit 6a4a93f767
4 changed files with 85 additions and 25 deletions

View File

@ -13,9 +13,7 @@ import logging
import os.path as op import os.path as op
import hsfs as fs import hsfs as fs
from hsfs.phys.bundle import Bundle
from hsutil.cocoa import install_exception_hook from hsutil.cocoa import install_exception_hook
from hsutil.str import get_file_ext
from hsutil import io, cocoa, job from hsutil import io, cocoa, job
from hsutil.reg import RegistrationRequired from hsutil.reg import RegistrationRequired
@ -29,19 +27,6 @@ JOBID2TITLE = {
app.JOB_DELETE: "Sending to Trash", app.JOB_DELETE: "Sending to Trash",
} }
class DGDirectory(fs.phys.Directory):
def _create_sub_dir(self,name,with_parent = True):
ext = get_file_ext(name)
if ext == 'app':
if with_parent:
parent = self
else:
parent = None
return Bundle(parent,name)
else:
return super(DGDirectory,self)._create_sub_dir(name,with_parent)
def demo_method(method): def demo_method(method):
def wrapper(self, *args, **kwargs): def wrapper(self, *args, **kwargs):
try: try:
@ -62,7 +47,6 @@ class DupeGuru(app.DupeGuru):
appdata = op.expanduser(op.join('~', '.hsoftdata', appdata_subdir)) appdata = op.expanduser(op.join('~', '.hsoftdata', appdata_subdir))
app.DupeGuru.__init__(self, data_module, appdata, appid) app.DupeGuru.__init__(self, data_module, appdata, appid)
self.progress = cocoa.ThreadedJobPerformer() self.progress = cocoa.ThreadedJobPerformer()
self.directories.dirclass = DGDirectory
self.display_delta_values = False self.display_delta_values = False
self.selected_dupes = [] self.selected_dupes = []
self.RefreshDetailsTable(None,None) self.RefreshDetailsTable(None,None)

View File

@ -5,9 +5,44 @@
# $Id$ # $Id$
# Copyright 2009 Hardcoded Software (http://www.hardcoded.net) # Copyright 2009 Hardcoded Software (http://www.hardcoded.net)
import app_cocoa, data from hsfs.phys import Directory as DirectoryBase
from hsfs.phys.bundle import Bundle
from hsutil.path import Path
from hsutil.str import get_file_ext
from . import app_cocoa, data
from .directories import Directories as DirectoriesBase, STATE_EXCLUDED
class DGDirectory(DirectoryBase):
def _create_sub_dir(self, name, with_parent = True):
ext = get_file_ext(name)
if ext == 'app':
parent = self if with_parent else None
return Bundle(parent, name)
else:
return super(DGDirectory, self)._create_sub_dir(name, with_parent)
class Directories(DirectoriesBase):
ROOT_PATH_TO_EXCLUDE = map(Path, ['/Library', '/Volumes', '/System', '/bin', '/sbin', '/opt', '/private'])
HOME_PATH_TO_EXCLUDE = [Path('Library')]
def __init__(self):
DirectoriesBase.__init__(self)
self.dirclass = DGDirectory
def _default_state_for_path(self, path):
result = DirectoriesBase._default_state_for_path(self, path)
if result is not None:
return result
if path in self.ROOT_PATH_TO_EXCLUDE:
return STATE_EXCLUDED
if path[:2] == Path('/Users') and path[3:] in self.HOME_PATH_TO_EXCLUDE:
return STATE_EXCLUDED
class DupeGuru(app_cocoa.DupeGuru): class DupeGuru(app_cocoa.DupeGuru):
def __init__(self): def __init__(self):
app_cocoa.DupeGuru.__init__(self, data, 'dupeguru', appid=4) app_cocoa.DupeGuru.__init__(self, data, 'dupeguru', appid=4)
self.directories = Directories()

View File

@ -49,11 +49,23 @@ class Directories(object):
return len(self._dirs) return len(self._dirs)
#---Private #---Private
def _get_files(self, from_dir, state=STATE_NORMAL): def _default_state_for_path(self, path):
state = self.states.get(from_dir.path, state) # Override this in subclasses to specify the state of some special folders.
if path[-1].startswith('.'): # hidden
return STATE_EXCLUDED
def _get_files(self, from_dir):
from_path = from_dir.path
state = self.GetState(from_path)
if state == STATE_EXCLUDED:
# Recursively get files from folders with lots of subfolder is expensive. However, there
# might be a subfolder in this path that is not excluded. What we want to do is to skim
# through self.states and see if we must continue, or we can stop right here to save time
if not any(p[:len(from_path)] == from_path for p in self.states):
return
result = [] result = []
for subdir in from_dir.dirs: for subdir in from_dir.dirs:
for file in self._get_files(subdir, state): for file in self._get_files(subdir):
yield file yield file
if state != STATE_EXCLUDED: if state != STATE_EXCLUDED:
for file in from_dir.files: for file in from_dir.files:
@ -103,8 +115,9 @@ class Directories(object):
try: try:
return self.states[path] return self.states[path]
except KeyError: except KeyError:
if path[-1].startswith('.'): # hidden default_state = self._default_state_for_path(path)
return STATE_EXCLUDED if default_state is not None:
return default_state
parent = path[:-1] parent = path[:-1]
if parent in self: if parent in self:
return self.GetState(parent) return self.GetState(parent)
@ -153,9 +166,13 @@ class Directories(object):
try: try:
if self.GetState(path) == state: if self.GetState(path) == state:
return return
self.states[path] = state # we don't want to needlessly fill self.states. if GetState returns the same thing
if (self.GetState(path[:-1]) == state) and (not path[-1].startswith('.')): # without an explicit entry, remove that entry
if path in self.states:
del self.states[path] del self.states[path]
if self.GetState(path) == state: # no need for an entry
return
self.states[path] = state
except LookupError: except LookupError:
pass pass

View File

@ -9,11 +9,13 @@ import os
import time import time
import shutil import shutil
from nose.tools import eq_
from hsutil import job, io from hsutil import job, io
from hsutil.path import Path from hsutil.path import Path
from hsutil.testcase import TestCase from hsutil.testcase import TestCase
import hsfs.phys import hsfs.phys
from hsfs.phys import phys_test from hsfs.tests import phys_test
from ..directories import * from ..directories import *
@ -270,3 +272,25 @@ class TCDirectories(TestCase):
self.assert_(isinstance(d.add_path(p2), hsfs.phys.Directory)) self.assert_(isinstance(d.add_path(p2), hsfs.phys.Directory))
self.assert_(isinstance(d.add_path(p1), MySpecialDirclass)) self.assert_(isinstance(d.add_path(p1), MySpecialDirclass))
def test_default_path_state_override(self):
# It's possible for a subclass to override the default state of a path
class MyDirectories(Directories):
def _default_state_for_path(self, path):
if 'foobar' in path:
return STATE_EXCLUDED
d = MyDirectories()
p1 = self.tmppath()
io.mkdir(p1 + 'foobar')
io.open(p1 + 'foobar/somefile', 'w').close()
io.mkdir(p1 + 'foobaz')
io.open(p1 + 'foobaz/somefile', 'w').close()
d.add_path(p1)
eq_(d.GetState(p1 + 'foobaz'), STATE_NORMAL)
eq_(d.GetState(p1 + 'foobar'), STATE_EXCLUDED)
eq_(len(list(d.get_files())), 1) # only the 'foobaz' file is there
# However, the default state can be changed
d.SetState(p1 + 'foobar', STATE_NORMAL)
eq_(d.GetState(p1 + 'foobar'), STATE_NORMAL)
eq_(len(list(d.get_files())), 2)