diff --git a/TODO.md b/TODO.md index ac85f71e..8303ec77 100644 --- a/TODO.md +++ b/TODO.md @@ -423,4 +423,4 @@ mkhomedir_helper or create ssh homes with bash.rc and such # account contacts inline, show provided fields and ignore the rest? # email usage -webkit-column-count:3;-moz-column-count:3;column-count:3; -# resources on service report +# Protect fucking search url and put into /admin/search and admin.py diff --git a/orchestra/admin/__init__.py b/orchestra/admin/__init__.py index b61f7980..49d603ab 100644 --- a/orchestra/admin/__init__.py +++ b/orchestra/admin/__init__.py @@ -1,9 +1,16 @@ +import itertools +from collections import OrderedDict from functools import update_wrapper from django.contrib import admin +from django.core.urlresolvers import reverse +from django.shortcuts import render, redirect +from django.utils.safestring import mark_safe +from django.utils.translation import ugettext_lazy as _ from .dashboard import * from .options import * +from ..core import accounts, services # monkey-patch admin.site in order to porvide some extra admin urls @@ -30,3 +37,52 @@ def get_urls(): ) return site_get_urls() + extra_patterns admin.site.get_urls = get_urls + + +def search(request): + query = request.GET.get('q', '') + if query.endswith('!'): + from ..contrib.accounts.models import Account + # Account direct access + query = query.replace('!', '') + try: + account = Account.objects.get(username=query) + except Account.DoesNotExist: + pass + else: + account_url = reverse('admin:accounts_account_change', args=(account.pk,)) + return redirect(account_url) + results = OrderedDict() + models = set() + for service in itertools.chain(services, accounts): + if service.search: + models.add(service.model) + models = sorted(models, key=lambda m: m._meta.verbose_name_plural.lower()) + total = 0 + for model in models: + try: + modeladmin = admin.site._registry[model] + except KeyError: + pass + else: + qs = modeladmin.get_queryset(request) + qs, search_use_distinct = modeladmin.get_search_results(request, qs, query) + if search_use_distinct: + qs = qs.distinct() + num = len(qs) + if num: + total += num + results[model._meta] = qs + title = _("{total} search results for '{query}'").format(total=total, query=query) + context = { + 'title': mark_safe(title), + 'total': total, + 'columns': min(int(total/17), 3), + 'query': query, + 'results': results, + 'search_autofocus': True, + } + return render(request, 'admin/orchestra/search.html', context) + + +admin.site.register_url(r'^search/$', search, 'orchestra_search_view') diff --git a/orchestra/contrib/accounts/admin.py b/orchestra/contrib/accounts/admin.py index 01de11a2..db58194b 100644 --- a/orchestra/contrib/accounts/admin.py +++ b/orchestra/contrib/accounts/admin.py @@ -8,6 +8,7 @@ from django.conf.urls import url from django.contrib import admin, messages from django.contrib.admin.utils import unquote from django.contrib.auth import admin as auth +from django.core.urlresolvers import reverse from django.http import HttpResponseRedirect from django.templatetags.static import static from django.utils.safestring import mark_safe @@ -152,6 +153,14 @@ class AccountListAdmin(AccountAdmin): if hasattr(response, 'context_data'): # user has submitted a change list change, we redirect directly to the add view # if there is only one result + query = request.GET.get('q', '') + if query: + try: + account = Account.objects.get(username=query) + except Account.DoesNotExist: + pass + else: + return HttpResponseRedirect('../?account=%i' % account.pk) queryset = response.context_data['cl'].queryset if len(queryset) == 1: return HttpResponseRedirect('../?account=%i' % queryset[0].pk) diff --git a/orchestra/templates/admin/orchestra/menu.html b/orchestra/templates/admin/orchestra/menu.html index 48901324..9adee58f 100644 --- a/orchestra/templates/admin/orchestra/menu.html +++ b/orchestra/templates/admin/orchestra/menu.html @@ -1,5 +1,6 @@ {% load i18n admin_tools_menu_tags %} {% if menu.children %} +