1# -*- coding: utf-8 -*- 2from __future__ import absolute_import 3 4import logging 5import os 6 7from django.conf import settings 8from django.core.exceptions import ImproperlyConfigured 9from django.core.files.storage import get_storage_class 10 11from .utils.loader import load_object 12from .utils.recursive_dictionary import RecursiveDictionaryWithExcludes 13 14 15logger = logging.getLogger(__name__) 16 17# FILER_IMAGE_MODEL setting is used to swap Image model. 18# If such global setting does not exist, it will be created at this point (with default model name). 19# This is needed especially when using this setting in migrations. 20if not hasattr(settings, 'FILER_IMAGE_MODEL'): 21 setattr(settings, 'FILER_IMAGE_MODEL', 'filer.Image') 22FILER_IMAGE_MODEL = settings.FILER_IMAGE_MODEL 23 24FILER_DEBUG = getattr(settings, 'FILER_DEBUG', False) # When True makes 25FILER_SUBJECT_LOCATION_IMAGE_DEBUG = getattr(settings, 'FILER_SUBJECT_LOCATION_IMAGE_DEBUG', False) 26FILER_WHITESPACE_COLOR = getattr(settings, 'FILER_WHITESPACE_COLOR', '#FFFFFF') 27 28FILER_0_8_COMPATIBILITY_MODE = getattr(settings, 'FILER_0_8_COMPATIBILITY_MODE', False) 29 30FILER_ENABLE_LOGGING = getattr(settings, 'FILER_ENABLE_LOGGING', False) 31if FILER_ENABLE_LOGGING: 32 FILER_ENABLE_LOGGING = ( 33 FILER_ENABLE_LOGGING and (getattr(settings, 'LOGGING') 34 and ('' in settings.LOGGING['loggers'] 35 or 'filer' in settings.LOGGING['loggers']))) 36 37FILER_ENABLE_PERMISSIONS = getattr(settings, 'FILER_ENABLE_PERMISSIONS', False) 38FILER_ALLOW_REGULAR_USERS_TO_ADD_ROOT_FOLDERS = getattr(settings, 'FILER_ALLOW_REGULAR_USERS_TO_ADD_ROOT_FOLDERS', False) 39FILER_IS_PUBLIC_DEFAULT = getattr(settings, 'FILER_IS_PUBLIC_DEFAULT', True) 40 41FILER_PAGINATE_BY = getattr(settings, 'FILER_PAGINATE_BY', 20) 42 43_ICON_SIZES = getattr(settings, 'FILER_ADMIN_ICON_SIZES', ('16', '32', '48', '64')) 44if not _ICON_SIZES: 45 raise ImproperlyConfigured('Please, configure FILER_ADMIN_ICON_SIZES') 46# Reliably sort by integer value, but keep icon size as string. 47# (There is some code in the wild that depends on this being strings.) 48FILER_ADMIN_ICON_SIZES = [str(i) for i in sorted([int(s) for s in _ICON_SIZES])] 49 50# Filer admin templates have specific icon sizes hardcoded: 32 and 48. 51_ESSENTIAL_ICON_SIZES = ('32', '48') 52if not all(x in FILER_ADMIN_ICON_SIZES for x in _ESSENTIAL_ICON_SIZES): 53 logger.warn( 54 "FILER_ADMIN_ICON_SIZES has not all of the essential icon sizes " 55 "listed: {}. Some icons might be missing in admin templates.".format( 56 _ESSENTIAL_ICON_SIZES)) 57 58# This is an ordered iterable that describes a list of 59# classes that I should check for when adding files 60FILER_FILE_MODELS = getattr( 61 settings, 'FILER_FILE_MODELS', 62 (FILER_IMAGE_MODEL, 'filer.File')) 63 64DEFAULT_FILE_STORAGE = getattr(settings, 'DEFAULT_FILE_STORAGE', 'django.core.files.storage.FileSystemStorage') 65 66MINIMAL_FILER_STORAGES = { 67 'public': { 68 'main': { 69 'ENGINE': None, 70 'OPTIONS': {}, 71 }, 72 'thumbnails': { 73 'ENGINE': None, 74 'OPTIONS': {}, 75 } 76 }, 77 'private': { 78 'main': { 79 'ENGINE': None, 80 'OPTIONS': {}, 81 }, 82 'thumbnails': { 83 'ENGINE': None, 84 'OPTIONS': {}, 85 }, 86 }, 87} 88 89 90DEFAULT_FILER_STORAGES = { 91 'public': { 92 'main': { 93 'ENGINE': DEFAULT_FILE_STORAGE, 94 'OPTIONS': {}, 95 'UPLOAD_TO': 'filer.utils.generate_filename.randomized', 96 'UPLOAD_TO_PREFIX': 'filer_public', 97 }, 98 'thumbnails': { 99 'ENGINE': DEFAULT_FILE_STORAGE, 100 'OPTIONS': {}, 101 'THUMBNAIL_OPTIONS': { 102 'base_dir': 'filer_public_thumbnails', 103 }, 104 }, 105 }, 106 'private': { 107 'main': { 108 'ENGINE': 'filer.storage.PrivateFileSystemStorage', 109 'OPTIONS': { 110 'location': os.path.abspath(os.path.join(settings.MEDIA_ROOT, '../smedia/filer_private')), 111 'base_url': '/smedia/filer_private/', 112 }, 113 'UPLOAD_TO': 'filer.utils.generate_filename.randomized', 114 'UPLOAD_TO_PREFIX': '', 115 }, 116 'thumbnails': { 117 'ENGINE': 'filer.storage.PrivateFileSystemStorage', 118 'OPTIONS': { 119 'location': os.path.abspath(os.path.join(settings.MEDIA_ROOT, '../smedia/filer_private_thumbnails')), 120 'base_url': '/smedia/filer_private_thumbnails/', 121 }, 122 'THUMBNAIL_OPTIONS': {}, 123 }, 124 }, 125} 126 127MINIMAL_FILER_SERVERS = { 128 'private': { 129 'main': { 130 'ENGINE': None, 131 'OPTIONS': {}, 132 }, 133 'thumbnails': { 134 'ENGINE': None, 135 'OPTIONS': {}, 136 }, 137 }, 138} 139 140DEFAULT_FILER_SERVERS = { 141 'private': { 142 'main': { 143 'ENGINE': 'filer.server.backends.default.DefaultServer', 144 'OPTIONS': {}, 145 }, 146 'thumbnails': { 147 'ENGINE': 'filer.server.backends.default.DefaultServer', 148 'OPTIONS': {}, 149 }, 150 }, 151} 152 153FILER_STORAGES = RecursiveDictionaryWithExcludes(MINIMAL_FILER_STORAGES, rec_excluded_keys=('OPTIONS', 'THUMBNAIL_OPTIONS')) 154if FILER_0_8_COMPATIBILITY_MODE: 155 user_filer_storages = { 156 'public': { 157 'main': { 158 'ENGINE': DEFAULT_FILE_STORAGE, 159 'UPLOAD_TO': 'filer.utils.generate_filename.randomized', 160 'UPLOAD_TO_PREFIX': getattr(settings, 'FILER_PUBLICMEDIA_PREFIX', 'filer_public'), 161 }, 162 'thumbnails': { 163 'ENGINE': DEFAULT_FILE_STORAGE, 164 'OPTIONS': {}, 165 'THUMBNAIL_OPTIONS': { 166 'base_dir': 'filer_public_thumbnails', 167 }, 168 }, 169 }, 170 'private': { 171 'main': { 172 'ENGINE': DEFAULT_FILE_STORAGE, 173 'UPLOAD_TO': 'filer.utils.generate_filename.randomized', 174 'UPLOAD_TO_PREFIX': getattr(settings, 'FILER_PRIVATEMEDIA_PREFIX', 'filer_private'), 175 }, 176 'thumbnails': { 177 'ENGINE': DEFAULT_FILE_STORAGE, 178 'OPTIONS': {}, 179 'THUMBNAIL_OPTIONS': { 180 'base_dir': 'filer_private_thumbnails', 181 }, 182 }, 183 }, 184 } 185else: 186 user_filer_storages = getattr(settings, 'FILER_STORAGES', {}) 187 188FILER_STORAGES.rec_update(user_filer_storages) 189 190 191def update_storage_settings(user_settings, defaults, s, t): 192 if not user_settings[s][t]['ENGINE']: 193 user_settings[s][t]['ENGINE'] = defaults[s][t]['ENGINE'] 194 user_settings[s][t]['OPTIONS'] = defaults[s][t]['OPTIONS'] 195 if t == 'main': 196 if 'UPLOAD_TO' not in user_settings[s][t]: 197 user_settings[s][t]['UPLOAD_TO'] = defaults[s][t]['UPLOAD_TO'] 198 if 'UPLOAD_TO_PREFIX' not in user_settings[s][t]: 199 user_settings[s][t]['UPLOAD_TO_PREFIX'] = defaults[s][t]['UPLOAD_TO_PREFIX'] 200 if t == 'thumbnails': 201 if 'THUMBNAIL_OPTIONS' not in user_settings[s][t]: 202 user_settings[s][t]['THUMBNAIL_OPTIONS'] = defaults[s][t]['THUMBNAIL_OPTIONS'] 203 return user_settings 204 205 206update_storage_settings(FILER_STORAGES, DEFAULT_FILER_STORAGES, 'public', 'main') 207update_storage_settings(FILER_STORAGES, DEFAULT_FILER_STORAGES, 'public', 'thumbnails') 208update_storage_settings(FILER_STORAGES, DEFAULT_FILER_STORAGES, 'private', 'main') 209update_storage_settings(FILER_STORAGES, DEFAULT_FILER_STORAGES, 'private', 'thumbnails') 210 211FILER_SERVERS = RecursiveDictionaryWithExcludes(MINIMAL_FILER_SERVERS, rec_excluded_keys=('OPTIONS',)) 212FILER_SERVERS.rec_update(getattr(settings, 'FILER_SERVERS', {})) 213 214 215def update_server_settings(settings, defaults, s, t): 216 if not settings[s][t]['ENGINE']: 217 settings[s][t]['ENGINE'] = defaults[s][t]['ENGINE'] 218 settings[s][t]['OPTIONS'] = defaults[s][t]['OPTIONS'] 219 return settings 220 221 222update_server_settings(FILER_SERVERS, DEFAULT_FILER_SERVERS, 'private', 'main') 223update_server_settings(FILER_SERVERS, DEFAULT_FILER_SERVERS, 'private', 'thumbnails') 224 225 226# Public media (media accessible without any permission checks) 227FILER_PUBLICMEDIA_STORAGE = get_storage_class(FILER_STORAGES['public']['main']['ENGINE'])(**FILER_STORAGES['public']['main']['OPTIONS']) 228FILER_PUBLICMEDIA_UPLOAD_TO = load_object(FILER_STORAGES['public']['main']['UPLOAD_TO']) 229if 'UPLOAD_TO_PREFIX' in FILER_STORAGES['public']['main']: 230 FILER_PUBLICMEDIA_UPLOAD_TO = load_object('filer.utils.generate_filename.prefixed_factory')(FILER_PUBLICMEDIA_UPLOAD_TO, FILER_STORAGES['public']['main']['UPLOAD_TO_PREFIX']) 231FILER_PUBLICMEDIA_THUMBNAIL_STORAGE = get_storage_class(FILER_STORAGES['public']['thumbnails']['ENGINE'])(**FILER_STORAGES['public']['thumbnails']['OPTIONS']) 232FILER_PUBLICMEDIA_THUMBNAIL_OPTIONS = FILER_STORAGES['public']['thumbnails']['THUMBNAIL_OPTIONS'] 233 234 235# Private media (media accessible through permissions checks) 236FILER_PRIVATEMEDIA_STORAGE = get_storage_class(FILER_STORAGES['private']['main']['ENGINE'])(**FILER_STORAGES['private']['main']['OPTIONS']) 237FILER_PRIVATEMEDIA_UPLOAD_TO = load_object(FILER_STORAGES['private']['main']['UPLOAD_TO']) 238if 'UPLOAD_TO_PREFIX' in FILER_STORAGES['private']['main']: 239 FILER_PRIVATEMEDIA_UPLOAD_TO = load_object('filer.utils.generate_filename.prefixed_factory')(FILER_PRIVATEMEDIA_UPLOAD_TO, FILER_STORAGES['private']['main']['UPLOAD_TO_PREFIX']) 240FILER_PRIVATEMEDIA_THUMBNAIL_STORAGE = get_storage_class(FILER_STORAGES['private']['thumbnails']['ENGINE'])(**FILER_STORAGES['private']['thumbnails']['OPTIONS']) 241FILER_PRIVATEMEDIA_THUMBNAIL_OPTIONS = FILER_STORAGES['private']['thumbnails']['THUMBNAIL_OPTIONS'] 242FILER_PRIVATEMEDIA_SERVER = load_object(FILER_SERVERS['private']['main']['ENGINE'])(**FILER_SERVERS['private']['main']['OPTIONS']) 243FILER_PRIVATEMEDIA_THUMBNAIL_SERVER = load_object(FILER_SERVERS['private']['thumbnails']['ENGINE'])(**FILER_SERVERS['private']['thumbnails']['OPTIONS']) 244 245# By default limit number of simultaneous uploads if we are using SQLite 246if settings.DATABASES['default']['ENGINE'].endswith('sqlite3'): 247 _uploader_connections = 1 248else: 249 _uploader_connections = 3 250FILER_UPLOADER_CONNECTIONS = getattr( 251 settings, 'FILER_UPLOADER_CONNECTIONS', _uploader_connections) 252 253FILER_DUMP_PAYLOAD = getattr(settings, 'FILER_DUMP_PAYLOAD', False) # Whether the filer shall dump the files payload 254 255FILER_CANONICAL_URL = getattr(settings, 'FILER_CANONICAL_URL', 'canonical/') 256