Create project, user authority pre-selected
[unfold.git] / unfold / collectstatic.py
1 from __future__ import print_function
2
3 import os
4 from django.conf import settings
5 from django.utils.datastructures import SortedDict
6 from django.contrib.staticfiles.finders import BaseFinder, FileSystemFinder
7 from django.core.files.storage import FileSystemStorage
8
9 # DEPRECATED # # http://nicks-liquid-soapbox.blogspot.fr/2011/03/splitting-path-to-list-in-python.html
10 # DEPRECATED # def splitpath(path, maxdepth=20):
11 # DEPRECATED #      ( head, tail ) = os.path.split(path)
12 # DEPRECATED #      return splitpath(head, maxdepth - 1) + [ tail ] \
13 # DEPRECATED #          if maxdepth and head and head != path \
14 # DEPRECATED #          else [ head or tail ]
15
16 # The plugin finder is responsible for collecting JS, CSS and PNG files from
17 # the plugins, which are not declared in the myslice.settings file unlike
18 # applications.
19 class PluginFinder(FileSystemFinder):
20     """
21     A static files finder that looks in the directory of each plugin as
22     specified in the source_dir attribute of the given storage class.
23     """
24     def __init__(self, *args, **kwargs):
25         # The list of plugins that are handled
26         self.locations = []
27         # Mapping of plugin module paths to storage instances
28         self.storages = SortedDict()
29         plugins_dir = self.get_immediate_subdirs(settings.PLUGIN_DIR)
30         for root in plugins_dir:
31             if not os.path.exists(root) or not os.path.isdir(root):
32                 continue
33             if ('', root) not in self.locations:
34                 self.locations.append(('', root))
35         for _, root in self.locations:
36             filesystem_storage = FileSystemStorage(location=root)
37             filesystem_storage.prefix = ''
38             self.storages[root] = filesystem_storage
39
40     def get_immediate_subdirs(self, dir):
41         return [os.path.join(dir, name, 'static') for name in os.listdir(dir) 
42                 if os.path.isdir(os.path.join(dir, name))]
43
44 # as these are a django-specific notion
45 class ThirdPartyFinder(BaseFinder):
46     """
47     A static files finder that looks in the directory of each third-party
48     resources and tries to preserve the location of each file
49     """
50     # third-party/MODULE/path/to/js
51     extensions = {
52         # PREFIX : EXTENSIONS
53 # third party stuff is not expected to provide templates,
54 #        ''   : ('.html',),
55         'js' : ('.js',),
56         'css': ('.css',),
57         'img': ('.png', '.ico',),
58         'fonts' : ('.svg', '.eot', '.ttf', '.woff'),
59     }
60
61     def find(self, search_path, all=False):
62         """
63         Given a relative file path this ought to find an
64         absolute file path.
65
66         If the ``all`` parameter is ``False`` (default) only
67         the first found file path will be returned; if set
68         to ``True`` a list of all found files paths is returned.
69         """
70         matches = []
71         #all_extensions = reduce(lambda x,y : x + y, extensions.values())
72
73         for (path, dirs, files) in os.walk(settings.THIRDPARTY_DIR):
74             for file in files:
75                 name, extension = os.path.splitext(file)
76
77                 for type, extensions in self.extensions.items():
78                     if not extension in extensions:
79                         continue
80                     if search_path == os.path.join(type, file):
81                         matched_path = os.path.join(path, file) 
82                         if not all:
83                             return matched_path
84                         print('ThirdPartyFinder, adding',matched_path)
85                         matches.append(matched_path)
86         return matches
87
88     def list(self, ignore_patterns):
89         """
90         Given an optional list of paths to ignore, this should return
91         a two item iterable consisting of the relative path and storage
92         instance.
93         """
94
95         for component in os.listdir(settings.THIRDPARTY_DIR):
96             # We are looking forward symlinks only
97             component_path = os.path.join(settings.THIRDPARTY_DIR, component)
98             if not os.path.islink(component_path) or not os.path.isdir(component_path):
99                 continue
100                 
101             for (path, dirs, files) in os.walk(component_path):
102                 for file in files:
103                     name, extension = os.path.splitext(file)
104
105                     for type, extensions in self.extensions.items():
106                         if not extension in extensions:
107                             continue
108                         filesystem_storage = FileSystemStorage(location=path)
109                         filesystem_storage.prefix = type
110                         yield file, filesystem_storage
111             
112 # DEPRECATED #         for (path, dirs, files) in os.walk(settings.THIRDPARTY_DIR):
113 # DEPRECATED #             component_path = path[len(settings.THIRDPARTY_DIR)+1:]
114 # DEPRECATED #             component_name = splitpath(component_path)[0]
115 # DEPRECATED #             print "PATH", path, " -- COMPONENT", component_name
116 # DEPRECATED #             if not os.path.islink(os.path.join(path, component_name)):
117 # DEPRECATED #                 print "IGNORED", component_name
118 # DEPRECATED #                 continue
119 # DEPRECATED #             print "COMPONENT ADDED: ", component_name
120 # DEPRECATED #             print "=="
121 # DEPRECATED # 
122 # DEPRECATED # 
123 # DEPRECATED #             for file in files:
124 # DEPRECATED #                 name, extension = os.path.splitext(file)
125 # DEPRECATED # 
126 # DEPRECATED #                 for type, extensions in self.extensions.items():
127 # DEPRECATED #                     if not extension in extensions:
128 # DEPRECATED #                         continue
129 # DEPRECATED #                     filesystem_storage = FileSystemStorage(location=path)
130 # DEPRECATED #                     filesystem_storage.prefix = type
131 # DEPRECATED #                     yield file, filesystem_storage
132
133 # XXX I commented this since it should be imported from django.contrib.staticfiles.finders -- jordan
134  
135 #class BaseFinder(object):
136 #    """
137 #    A base file finder to be used for custom staticfiles finder classes.
138 #    """
139 #
140 #    def list(self, ignore_patterns):
141 #        """
142 #        Given an optional list of paths to ignore, this should return
143 #        a two item iterable consisting of the relative path and storage
144 #        instance.
145 #        """
146 #        raise NotImplementedError()
147