2 from django.conf import settings
3 from django.utils.datastructures import SortedDict
4 from django.contrib.staticfiles.finders import BaseFinder, FileSystemFinder
5 from django.core.files.storage import FileSystemStorage
7 class PluginFinder(FileSystemFinder):
9 A static files finder that looks in the directory of each plugin as
10 specified in the source_dir attribute of the given storage class.
12 def __init__(self, *args, **kwargs):
13 # The list of plugins that are handled
15 # Mapping of plugin module paths to storage instances
16 self.storages = SortedDict()
17 plugins_dir = self.get_immediate_subdirs(settings.PLUGIN_DIR)
18 for root in plugins_dir:
19 if not os.path.exists(root) or not os.path.isdir(root):
21 if ('', root) not in self.locations:
22 self.locations.append(('', root))
23 for _, root in self.locations:
24 filesystem_storage = FileSystemStorage(location=root)
25 filesystem_storage.prefix = ''
26 self.storages[root] = filesystem_storage
28 def get_immediate_subdirs(self, dir):
29 return [os.path.join(dir, name, 'static') for name in os.listdir(dir)
30 if os.path.isdir(os.path.join(dir, name))]
32 class ThirdPartyFinder(BaseFinder):
34 A static files inder that looks in the directory of each third-party
35 resources and tries to preserve the location of each file
37 # third-party/MODULE/path/to/js
43 'img': ('.png', '.ico',),
46 def find(self, search_path, all=False):
48 Given a relative file path this ought to find an
51 If the ``all`` parameter is ``False`` (default) only
52 the first found file path will be returned; if set
53 to ``True`` a list of all found files paths is returned.
56 #all_extensions = reduce(lambda x,y : x + y, extensions.values())
58 for (path, dirs, files) in os.walk(settings.THIRDPARTY_DIR):
60 name, extension = os.path.splitext(file)
62 for type, extensions in self.extensions.items():
63 if not extension in extensions:
65 if search_path == os.path.join(type, file):
66 matched_path = os.path.join(path, file)
69 matches.append(matched_path)
72 def list(self, ignore_patterns):
74 Given an optional list of paths to ignore, this should return
75 a two item iterable consisting of the relative path and storage
78 for (path, dirs, files) in os.walk(settings.THIRDPARTY_DIR):
80 name, extension = os.path.splitext(file)
82 for type, extensions in self.extensions.items():
83 if not extension in extensions:
85 filesystem_storage = FileSystemStorage(location=path)
86 filesystem_storage.prefix = type
87 yield file, filesystem_storage
89 class BaseFinder(object):
91 A base file finder to be used for custom staticfiles finder classes.
94 def list(self, ignore_patterns):
96 Given an optional list of paths to ignore, this should return
97 a two item iterable consisting of the relative path and storage
100 raise NotImplementedError()