diff --git a/apps/common/conf/settings.py b/apps/common/conf/settings.py index d97cad6b06..7e22f83d27 100644 --- a/apps/common/conf/settings.py +++ b/apps/common/conf/settings.py @@ -2,7 +2,7 @@ from django.utils.translation import ugettext_lazy as _ -from main.api import register_setting +from smart_settings.api import register_setting from common.literals import PAGE_SIZE_LETTER, PAGE_ORIENTATION_PORTRAIT diff --git a/apps/converter/conf/settings.py b/apps/converter/conf/settings.py index bdfe8a9b31..219863c36c 100644 --- a/apps/converter/conf/settings.py +++ b/apps/converter/conf/settings.py @@ -1,7 +1,7 @@ """Configuration options for the converter app""" from django.utils.translation import ugettext_lazy as _ -from main.api import register_settings +from smart_settings.api import register_settings register_settings( namespace=u'converter', diff --git a/apps/documents/conf/settings.py b/apps/documents/conf/settings.py index 50dbd06ccc..d504fef996 100644 --- a/apps/documents/conf/settings.py +++ b/apps/documents/conf/settings.py @@ -9,7 +9,7 @@ from django.contrib.auth.models import User from common.utils import proper_name from storage.backends.filebasedstorage import FileBasedStorage -from main.api import register_settings +from smart_settings.api import register_settings def default_checksum(x): diff --git a/apps/dynamic_search/conf/settings.py b/apps/dynamic_search/conf/settings.py index d710be81d6..b9ef4077ea 100644 --- a/apps/dynamic_search/conf/settings.py +++ b/apps/dynamic_search/conf/settings.py @@ -2,7 +2,7 @@ from django.utils.translation import ugettext_lazy as _ -from main.api import register_settings +from smart_settings.api import register_settings register_settings( namespace=u'dynamic_search', @@ -12,4 +12,3 @@ register_settings( {'name': u'LIMIT', 'global_name': u'SEARCH_LIMIT', 'default': 100, 'description': _(u'Maximum amount search hits to fetch and display.')}, ] ) - diff --git a/apps/filesystem_serving/conf/settings.py b/apps/filesystem_serving/conf/settings.py index 91bee7fece..e014493a6d 100644 --- a/apps/filesystem_serving/conf/settings.py +++ b/apps/filesystem_serving/conf/settings.py @@ -1,6 +1,6 @@ """Configuration options for the filesystem_serving app""" -from main.api import register_settings +from smart_settings.api import register_settings register_settings( namespace=u'filesystem_serving', @@ -12,4 +12,3 @@ register_settings( {'name': u'FILESERVING_ENABLE', 'global_name': u'FILESYSTEM_FILESERVING_ENABLE', 'default': True} ] ) - diff --git a/apps/main/__init__.py b/apps/main/__init__.py index dd2c85ca39..ddbfcd248c 100644 --- a/apps/main/__init__.py +++ b/apps/main/__init__.py @@ -5,14 +5,12 @@ from permissions import role_list from user_management import user_list from main.conf.settings import SIDE_BAR_SEARCH -from main.conf import settings as main_settings -from main.api import register_setting def is_superuser(context): return context['request'].user.is_staff or context['request'].user.is_superuser -check_settings = {'text': _(u'settings'), 'view': 'check_settings', 'famfam': 'cog'} +check_settings = {'text': _(u'settings'), 'view': 'setting_list', 'famfam': 'cog'} statistics = {'text': _(u'statistics'), 'view': 'statistics', 'famfam': 'table'} diagnostics = {'text': _(u'diagnostics'), 'view': 'diagnostics', 'famfam': 'pill'} tools = {'text': _(u'tools'), 'view': 'tools_menu', 'famfam': 'wrench'} @@ -34,7 +32,7 @@ main_menu = [ tools, statistics, diagnostics, sentry ], 'famfam': 'wrench', 'name': 'tools', 'position': 7}, - {'text': _(u'setup'), 'view': 'check_settings', 'links': [ + {'text': _(u'setup'), 'view': 'setting_list', 'links': [ check_settings, role_list, user_list, admin_site ], 'famfam': 'cog', 'name': 'setup', 'position': 8}, @@ -60,6 +58,3 @@ def get_version(): return ''.join(vers) __version__ = get_version() - - -#register_setting(u'main', main_settings, u'SIDE_BAR_SEARCH', u'MAIN_SIDE_BAR_SEARCH') diff --git a/apps/main/api.py b/apps/main/api.py index 9fd56a64d0..81678000e5 100644 --- a/apps/main/api.py +++ b/apps/main/api.py @@ -1,12 +1,9 @@ from django.core.urlresolvers import reverse from django.utils.functional import lazy -from django.conf import settings as django_settings -from django.utils.importlib import import_module diagnostics = {} tools = {} reverse_lazy = lazy(reverse, str) -settings = {} def register_diagnostic(namespace, title, link): @@ -23,47 +20,3 @@ def register_tool(link, title=None, namespace=None): link['url'] = link.get('url', reverse_lazy(link['view'])) namespace_dict['links'].append(link) tools[namespace] = namespace_dict - - -def register_setting(namespace, module, name, global_name, default, exists=False, description=u'', hidden=False): - # Create namespace if it doesn't exists - settings.setdefault(namespace, []) - - # If passed a string and not a module, import it - if isinstance(module, basestring): - module = import_module(module) - - setting = { - 'module': module, - 'name': name, - 'global_name': global_name, - 'exists': exists, - 'description': description, - 'default': default, - 'hidden': hidden, - } - - # Avoid multiple appends - if setting not in settings[namespace]: - settings[namespace].append(setting) - - # Get the global value - value = getattr(django_settings, global_name, default) - - # Create the local entity - setattr(module, name, value) - return value - - -def register_settings(namespace, module, settings): - for setting in settings: - register_setting( - namespace, - module, - setting['name'], - setting['global_name'], - setting['default'], - setting.get('exists', False), - setting.get('description', u''), - setting.get('hidden', False), - ) diff --git a/apps/main/conf/settings.py b/apps/main/conf/settings.py index 1285a1cb56..80c5d7d0bc 100644 --- a/apps/main/conf/settings.py +++ b/apps/main/conf/settings.py @@ -1,7 +1,7 @@ """Configuration options for the main app""" from django.utils.translation import ugettext_lazy as _ -from main.api import register_setting +from smart_settings.api import register_setting register_setting( namespace=u'main', diff --git a/apps/main/urls.py b/apps/main/urls.py index 6c20d63064..7dfcdac26a 100644 --- a/apps/main/urls.py +++ b/apps/main/urls.py @@ -1,9 +1,7 @@ from django.conf.urls.defaults import patterns, url - urlpatterns = patterns('main.views', url(r'^$', 'home', (), 'home'), - url(r'^check_settings/$', 'check_settings', (), 'check_settings'), url(r'^tools_menu/$', 'tools_menu', (), 'tools_menu'), url(r'^statistics/$', 'statistics', (), 'statistics'), url(r'^diagnostics/$', 'diagnostics_view', (), 'diagnostics'), diff --git a/apps/main/views.py b/apps/main/views.py index 9d342456dd..ec394ea949 100644 --- a/apps/main/views.py +++ b/apps/main/views.py @@ -3,19 +3,11 @@ from django.template import RequestContext from django.utils.translation import ugettext_lazy as _ from django.core.exceptions import PermissionDenied -from common.utils import exists_with_famfam, return_type -#from common.conf import settings as common_settings -#from documents.conf import settings as documents_settings -#from documents.statistics import get_statistics as documents_statistics -#from converter.conf import settings as converter_settings -#from ocr.conf import settings as ocr_settings -#from ocr.statistics import get_statistics as ocr_statistics -#from filesystem_serving.conf import settings as filesystem_serving_settings -#from dynamic_search.conf import settings as search_settings +from documents.statistics import get_statistics as documents_statistics +from ocr.statistics import get_statistics as ocr_statistics from permissions.api import check_permissions -from main.conf import settings as main_settings -from main.api import diagnostics, tools, settings +from main.api import diagnostics, tools def home(request): @@ -23,118 +15,6 @@ def home(request): context_instance=RequestContext(request)) -def check_settings(request): - """ - settings = [ - - {'name': 'DOCUMENTS_METADATA_AVAILABLE_FUNCTIONS', 'value': documents_settings.AVAILABLE_FUNCTIONS}, - {'name': 'DOCUMENTS_METADATA_AVAILABLE_MODELS', 'value': documents_settings.AVAILABLE_MODELS}, - {'name': 'DOCUMENTS_INDEXING_AVAILABLE_INDEXING_FUNCTIONS', 'value': documents_settings.AVAILABLE_INDEXING_FUNCTIONS}, - {'name': 'DOCUMENTS_USE_STAGING_DIRECTORY', 'value': documents_settings.USE_STAGING_DIRECTORY}, - {'name': 'DOCUMENTS_STAGING_DIRECTORY', 'value': documents_settings.STAGING_DIRECTORY, 'exists': True}, - {'name': 'DOCUMENTS_DELETE_STAGING_FILE_AFTER_UPLOAD', 'value': documents_settings.DELETE_STAGING_FILE_AFTER_UPLOAD}, - {'name': 'DOCUMENTS_STAGING_FILES_PREVIEW_SIZE', 'value': documents_settings.STAGING_FILES_PREVIEW_SIZE}, - {'name': 'DOCUMENTS_CHECKSUM_FUNCTION', 'value': documents_settings.CHECKSUM_FUNCTION}, - {'name': 'DOCUMENTS_UUID_FUNTION', 'value': documents_settings.UUID_FUNCTION}, - {'name': 'DOCUMENTS_STORAGE_BACKEND', 'value': documents_settings.STORAGE_BACKEND}, - {'name': 'DOCUMENTS_PREVIEW_SIZE', 'value': documents_settings.PREVIEW_SIZE}, - {'name': 'DOCUMENTS_THUMBNAIL_SIZE', 'value': documents_settings.THUMBNAIL_SIZE}, - {'name': 'DOCUMENTS_DISPLAY_SIZE', 'value': documents_settings.DISPLAY_SIZE}, - {'name': 'DOCUMENTS_ENABLE_SINGLE_DOCUMENT_UPLOAD', 'value': documents_settings.ENABLE_SINGLE_DOCUMENT_UPLOAD}, - {'name': 'DOCUMENTS_UNCOMPRESS_COMPRESSED_LOCAL_FILES', 'value': documents_settings.UNCOMPRESS_COMPRESSED_LOCAL_FILES}, - {'name': 'DOCUMENTS_UNCOMPRESS_COMPRESSED_STAGING_FILES', 'value': documents_settings.UNCOMPRESS_COMPRESSED_STAGING_FILES}, - {'name': 'DOCUMENTS_ZOOM_PERCENT_STEP', 'value': documents_settings.ZOOM_PERCENT_STEP}, - {'name': 'DOCUMENTS_ZOOM_MAX_LEVEL', 'value': documents_settings.ZOOM_MAX_LEVEL}, - {'name': 'DOCUMENTS_ZOOM_MIN_LEVEL', 'value': documents_settings.ZOOM_MIN_LEVEL}, - {'name': 'DOCUMENTS_ROTATION_STEP', 'value': documents_settings.ROTATION_STEP}, - - #Groups - {'name': 'DOCUMENTS_GROUP_SHOW_EMPTY', 'value': documents_settings.GROUP_SHOW_EMPTY}, - {'name': 'DOCUMENTS_RECENT_COUNT', 'value': documents_settings.RECENT_COUNT}, - - #Filesystem_serving - {'name': 'FILESYSTEM_FILESERVING_ENABLE', 'value': filesystem_serving_settings.FILESERVING_ENABLE}, - {'name': 'FILESYSTEM_FILESERVING_PATH', 'value': filesystem_serving_settings.FILESERVING_PATH, 'exists': True}, - {'name': 'FILESYSTEM_SLUGIFY_PATHS', 'value': filesystem_serving_settings.SLUGIFY_PATHS}, - {'name': 'FILESYSTEM_MAX_RENAME_COUNT', 'value': filesystem_serving_settings.MAX_RENAME_COUNT}, - - # Common - {'name': 'COMMON_TEMPORARY_DIRECTORY', - 'value': common_settings.TEMPORARY_DIRECTORY, 'exists': True, - 'description': common_settings.setting_description}, - {'name': 'COMMON_DEFAULT_PAPER_SIZE', - 'value': common_settings.PAGE_SIZE_LETTER}, - {'name': 'COMMON_DEFAULT_PAGE_ORIENTATION', - 'value': common_settings.PAGE_ORIENTATION_PORTRAIT}, - - # Converter - {'name': 'CONVERTER_UNPAPER_PATH', - 'value': converter_settings.UNPAPER_PATH, 'exists': True, - 'description': converter_settings.setting_description}, - {'name': 'CONVERTER_IM_CONVERT_PATH', - 'value': converter_settings.IM_CONVERT_PATH, 'exists': True, - 'description': converter_settings.setting_description}, - {'name': 'CONVERTER_IM_IDENTIFY_PATH', - 'value': converter_settings.IM_IDENTIFY_PATH, 'exists': True, - 'description': converter_settings.setting_description}, - {'name': 'CONVERTER_GM_PATH', - 'value': converter_settings.GM_PATH, 'exists': True, - 'description': converter_settings.setting_description}, - {'name': 'CONVERTER_GM_SETTINGS', 'value': converter_settings.GM_SETTINGS}, - {'name': 'CONVERTER_GRAPHICS_BACKEND', - 'value': converter_settings.GRAPHICS_BACKEND, - 'description': converter_settings.setting_description}, - {'name': 'CONVERTER_UNOCONV_PATH', - 'value': converter_settings.UNOCONV_PATH, 'exists': True}, - {'name': 'CONVERTER_OCR_OPTIONS', 'value': converter_settings.OCR_OPTIONS}, - {'name': 'CONVERTER_DEFAULT_OPTIONS', 'value': converter_settings.DEFAULT_OPTIONS}, - {'name': 'CONVERTER_LOW_QUALITY_OPTIONS', 'value': converter_settings.LOW_QUALITY_OPTIONS}, - {'name': 'CONVERTER_HIGH_QUALITY_OPTIONS', 'value': converter_settings.HIGH_QUALITY_OPTIONS}, - - # OCR - {'name': 'OCR_AUTOMATIC_OCR', 'value': ocr_settings.AUTOMATIC_OCR}, - {'name': 'OCR_TESSERACT_PATH', 'value': ocr_settings.TESSERACT_PATH, 'exists': True}, - {'name': 'OCR_TESSERACT_LANGUAGE', 'value': ocr_settings.TESSERACT_LANGUAGE}, - {'name': 'OCR_NODE_CONCURRENT_EXECUTION', 'value': ocr_settings.NODE_CONCURRENT_EXECUTION}, - {'name': 'OCR_REPLICATION_DELAY', 'value': ocr_settings.REPLICATION_DELAY}, - {'name': 'OCR_PDFTOTEXT_PATH', 'value': ocr_settings.PDFTOTEXT_PATH, 'exists': True}, - {'name': 'OCR_QUEUE_PROCESSING_INTERVAL', 'value': ocr_settings.QUEUE_PROCESSING_INTERVAL}, - {'name': 'OCR_CACHE_URI', 'value': ocr_settings.CACHE_URI}, - - # Search - {'name': 'SEARCH_LIMIT', 'value': search_settings.LIMIT}, - ] - """ - new_settings = [] - for namespace, sub_settings in settings.items(): - for sub_setting in sub_settings: - if not sub_setting.get('hidden', False): - new_settings.append({ - 'module': sub_setting['module'], - 'name': sub_setting['name'], - 'global_name': sub_setting['global_name'], - 'description': sub_setting.get('description', None), - 'exists': sub_setting.get('exists', False), - 'default': sub_setting['default'], - }) - context = { - 'title': _(u'settings'), - 'object_list': new_settings, - 'hide_link': True, - 'hide_object': True, - 'extra_columns': [ - {'name': _(u'name'), 'attribute': 'global_name'}, - {'name': _(u'default'), 'attribute': lambda x: return_type(x['default'])}, - {'name': _(u'value'), 'attribute': lambda x: return_type(getattr(x['module'], x['name']))}, - {'name': _(u'description'), 'attribute': 'description'}, - {'name': _(u'exists'), 'attribute': lambda x: exists_with_famfam(getattr(x['module'], x['name'])) if x['exists'] else ''}, - ] - } - - return render_to_response('generic_list.html', context, - context_instance=RequestContext(request)) - - def tools_menu(request): user_tools = {} for namespace, values in tools.items(): diff --git a/apps/ocr/conf/settings.py b/apps/ocr/conf/settings.py index 309d68ac04..e9024b7152 100644 --- a/apps/ocr/conf/settings.py +++ b/apps/ocr/conf/settings.py @@ -2,7 +2,7 @@ from django.utils.translation import ugettext_lazy as _ -from main.api import register_settings +from smart_settings.api import register_settings register_settings( namespace=u'ocr', @@ -18,4 +18,3 @@ register_settings( {'name': u'CACHE_URI', 'global_name': u'OCR_CACHE_URI', 'default': None, 'description': _(u'URI in the form: "memcached://127.0.0.1:11211/" to specify a cache backend to use for locking. Multiple hosts can be specified separated by a semicolon.')} ] ) - diff --git a/apps/ocr/tasks.py b/apps/ocr/tasks.py index 20a726ad29..d47fcff96b 100644 --- a/apps/ocr/tasks.py +++ b/apps/ocr/tasks.py @@ -6,7 +6,7 @@ from random import random from django.db.models import Q from django.utils.translation import ugettext as _ from django.core.cache import get_cache - + from celery.decorators import task, periodic_task from celery.task.control import inspect @@ -92,7 +92,7 @@ def reset_orphans(): def task_process_document_queues(): if not cache_backend: random_delay() - + reset_orphans() q_pending = Q(state=QUEUEDOCUMENT_STATE_PENDING) q_delayed = Q(delay=True) diff --git a/apps/permissions/conf/settings.py b/apps/permissions/conf/settings.py index 16ec61ae15..6132219834 100644 --- a/apps/permissions/conf/settings.py +++ b/apps/permissions/conf/settings.py @@ -1,7 +1,7 @@ """Configuration options for the permissions app""" from django.utils.translation import ugettext_lazy as _ -from main.api import register_settings +from smart_settings.api import register_settings register_settings( namespace=u'permissions', diff --git a/apps/smart_settings/__init__.py b/apps/smart_settings/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/smart_settings/api.py b/apps/smart_settings/api.py new file mode 100644 index 0000000000..e2e5063d87 --- /dev/null +++ b/apps/smart_settings/api.py @@ -0,0 +1,48 @@ +from django.conf import settings as django_settings +from django.utils.importlib import import_module + +settings = {} + + +def register_setting(namespace, module, name, global_name, default, exists=False, description=u'', hidden=False): + # Create namespace if it doesn't exists + settings.setdefault(namespace, []) + + # If passed a string and not a module, import it + if isinstance(module, basestring): + module = import_module(module) + + setting = { + 'module': module, + 'name': name, + 'global_name': global_name, + 'exists': exists, + 'description': description, + 'default': default, + 'hidden': hidden, + } + + # Avoid multiple appends + if setting not in settings[namespace]: + settings[namespace].append(setting) + + # Get the global value + value = getattr(django_settings, global_name, default) + + # Create the local entity + setattr(module, name, value) + return value + + +def register_settings(namespace, module, settings): + for setting in settings: + register_setting( + namespace, + module, + setting['name'], + setting['global_name'], + setting['default'], + setting.get('exists', False), + setting.get('description', u''), + setting.get('hidden', False), + ) diff --git a/apps/smart_settings/models.py b/apps/smart_settings/models.py new file mode 100644 index 0000000000..71a8362390 --- /dev/null +++ b/apps/smart_settings/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/apps/smart_settings/tests.py b/apps/smart_settings/tests.py new file mode 100644 index 0000000000..2247054b35 --- /dev/null +++ b/apps/smart_settings/tests.py @@ -0,0 +1,23 @@ +""" +This file demonstrates two different styles of tests (one doctest and one +unittest). These will both pass when you run "manage.py test". + +Replace these with more appropriate tests for your application. +""" + +from django.test import TestCase + +class SimpleTest(TestCase): + def test_basic_addition(self): + """ + Tests that 1 + 1 always equals 2. + """ + self.failUnlessEqual(1 + 1, 2) + +__test__ = {"doctest": """ +Another way to test that 1 + 1 is equal to 2. + +>>> 1 + 1 == 2 +True +"""} + diff --git a/apps/smart_settings/urls.py b/apps/smart_settings/urls.py new file mode 100644 index 0000000000..4ba642d50a --- /dev/null +++ b/apps/smart_settings/urls.py @@ -0,0 +1,5 @@ +from django.conf.urls.defaults import patterns, url + +urlpatterns = patterns('smart_settings.views', + url(r'^list/$', 'setting_list', (), 'setting_list'), +) diff --git a/apps/smart_settings/views.py b/apps/smart_settings/views.py new file mode 100644 index 0000000000..0839777901 --- /dev/null +++ b/apps/smart_settings/views.py @@ -0,0 +1,38 @@ +from django.shortcuts import render_to_response +from django.template import RequestContext +from django.utils.translation import ugettext_lazy as _ + +from common.utils import exists_with_famfam, return_type + +from smart_settings.api import settings + + +def setting_list(request): + new_settings = [] + for namespace, sub_settings in settings.items(): + for sub_setting in sub_settings: + if not sub_setting.get('hidden', False): + new_settings.append({ + 'module': sub_setting['module'], + 'name': sub_setting['name'], + 'global_name': sub_setting['global_name'], + 'description': sub_setting.get('description', None), + 'exists': sub_setting.get('exists', False), + 'default': sub_setting['default'], + }) + context = { + 'title': _(u'settings'), + 'object_list': new_settings, + 'hide_link': True, + 'hide_object': True, + 'extra_columns': [ + {'name': _(u'name'), 'attribute': 'global_name'}, + {'name': _(u'default'), 'attribute': lambda x: return_type(x['default'])}, + {'name': _(u'value'), 'attribute': lambda x: return_type(getattr(x['module'], x['name']))}, + {'name': _(u'description'), 'attribute': 'description'}, + {'name': _(u'exists'), 'attribute': lambda x: exists_with_famfam(getattr(x['module'], x['name'])) if x['exists'] else ''}, + ] + } + + return render_to_response('generic_list.html', context, + context_instance=RequestContext(request)) diff --git a/apps/storage/conf/settings.py b/apps/storage/conf/settings.py index 7ef087d111..edd332734a 100644 --- a/apps/storage/conf/settings.py +++ b/apps/storage/conf/settings.py @@ -1,7 +1,7 @@ """Configuration options for the storage app""" from django.utils.translation import ugettext_lazy as _ -from main.api import register_settings +from smart_settings.api import register_settings register_settings( namespace=u'storage', diff --git a/apps/web_theme/conf/settings.py b/apps/web_theme/conf/settings.py index 8370914cb6..c1d0ef7292 100644 --- a/apps/web_theme/conf/settings.py +++ b/apps/web_theme/conf/settings.py @@ -1,7 +1,7 @@ """Configuration options for the web_theme app""" from django.utils.translation import ugettext_lazy as _ -from main.api import register_settings +from smart_settings.api import register_settings register_settings( namespace=u'web_theme', diff --git a/settings.py b/settings.py index 383ace3c2c..407fa95034 100644 --- a/settings.py +++ b/settings.py @@ -120,6 +120,7 @@ INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.admindocs', 'django.contrib.comments', + 'smart_settings', 'navigation', 'web_theme', 'main', diff --git a/urls.py b/urls.py index e99cbfa7e7..b3520b487f 100644 --- a/urls.py +++ b/urls.py @@ -20,6 +20,7 @@ urlpatterns = patterns('', (r'^sentry/', include('sentry.urls')), (r'^comments/', include('document_comments.urls')), (r'^user_management/', include('user_management.urls')), + (r'^settings/', include('smart_settings.urls')), )