# (c) Copyright 2009-2010. CodeWeavers, Inc.
import c4profiles
import globtree
import bottlequery
def find_files(bottlename, path, max_results=-1):
files = []
dirs = []
output = bottlequery.BottleManipulator(bottlename).send('findfiles %s %s' % (max_results, path)).get()
for line in output.split('\n'):
if line.startswith('file '):
files.append(line[5:])
elif line.startswith('dir '):
dirname = line[4:]
if dirname not in ('.', '..'):
dirs.append(dirname)
elif line in ('errno 2', 'errno 3', 'errno 5', 'errno 267'):
raise bottlequery.NotFoundError
elif line:
raise Exception("got unexpected data: %s" % line)
return dirs, files
class FileGlobTree(globtree.GlobTree):
# pylint: disable=W0221
# The listdir, exists, and isdir methods take a bottle argument not present
# in the parent class (but implicitly allowed by the *args, **kwargs).
# Pylint is either not smart enough to notice *args, **kwargs or doesn't
# care.
environ = None
def listdir(self, path, bottlename='default'):
if not path:
return (('c:',), ())
winpath = '%s*' % path.replace('/', '\\')
try:
return find_files(bottlename, winpath)
except bottlequery.NotFoundError:
return (), ()
def exists(self, path, bottlename='default'):
if not path:
return True
if path.endswith(':') and len(path) == 2:
# x: can only be properly tested as a directory
path = '%s/' % path
if path.endswith('/'):
winpath = '%s*' % path.replace('/', '\\')
else:
winpath = path.replace('/', '\\')
try:
find_files(bottlename, winpath, max_results=0)
return True
except bottlequery.NotFoundError:
return False
def isdir(self, _path, _bottlename='default'):
return True
def add_profile(self, profile, bottlename='default'):
if profile.app_profile:
if not self.environ:
self.environ = bottlequery.get_win_environ(bottlename, c4profiles.ENVIRONMENT_VARIABLES)
for glob in profile.app_profile.installed_file_globs:
self.add_glob(bottlequery.expand_win_string(self.environ, glob).replace('\\', '/'), profile)
class RegistryGlobTree(globtree.GlobTree):
# pylint: disable=W0221
# The listdir, exists, and isdir methods take a bottle argument not present
# in the parent class (but implicitly allowed by the *args, **kwargs).
# Pylint is either not smart enough to notice *args, **kwargs or doesn't
# care.
#####
#
# Globbing
#
#####
_root_keys = set(['hkey_classes_root', 'hkey_current_user', 'hkey_local_machine', 'hkey_users'])
def listdir(self, path, bottlename='default'):
if not path:
return (self._root_keys, ())
path = path.lower().replace('/', '\\')
if not path.endswith('\\'):
path = '%s\\' % path
try:
keys, _values = bottlequery.get_registry_key(bottlename, path)
return keys, ()
except bottlequery.NotFoundError:
return (), ()
def exists(self, path, bottlename='default'):
if not path:
return True
path = path.lower().replace('/', '\\')
if not path.endswith('\\'):
path = '%s\\' % path
try:
bottlequery.get_registry_key(bottlename, path)
return True
except bottlequery.NotFoundError:
return False
def isdir(self, _path, _bottlename='default'):
return True
#####
#
# Initialization
#
#####
def add_profile(self, profile):
if profile.app_profile:
for glob in profile.app_profile.installed_registry_globs:
self.add_glob(glob.key_glob, (profile, glob))
@staticmethod
def get(profiles):
"""Returns a RegistryGlobTree() object for the specified C4ProfilesSet
object.
"""
if 'RegistryGlobTree' not in profiles.userdata:
reg_glob = RegistryGlobTree()
for profile in profiles.values():
reg_glob.add_profile(profile)
profiles.userdata.setdefault('RegistryGlobTree', reg_glob)
return profiles.userdata['RegistryGlobTree']