From 21973244d51d342ce40ab7c20ea8b46fb5d4334d Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Wed, 21 Jan 2015 16:25:16 -0200 Subject: [PATCH] Remove haystack search from dashboard an profile --- colab/accounts/views.py | 51 ++++++++++++--------------------------------------- colab/home/views.py | 55 +++++++++++++++++++++++++------------------------------ colab/proxy/gitlab/apps.py | 32 +++++++++++++++++++++++++++++++- colab/proxy/jenkins/apps.py | 2 ++ colab/proxy/noosfero/apps.py | 2 ++ colab/proxy/redmine/apps.py | 2 ++ colab/proxy/trac/apps.py | 2 ++ colab/search/preview_block.py | 15 +++++++++++++++ colab/search/templates/search/search-message-preview.html | 1 - colab/search/utils.py | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 169 insertions(+), 71 deletions(-) create mode 100644 colab/search/preview_block.py diff --git a/colab/accounts/views.py b/colab/accounts/views.py index f2f9187..9bf04b0 100644 --- a/colab/accounts/views.py +++ b/colab/accounts/views.py @@ -1,5 +1,7 @@ #!/usr/bin/env python # encoding: utf-8 +import importlib +import inspect from collections import OrderedDict @@ -15,6 +17,7 @@ from django.shortcuts import render, redirect, get_object_or_404 from django.core.urlresolvers import reverse from django.core.exceptions import PermissionDenied from django.views.generic import DetailView, UpdateView, TemplateView +from django.apps import apps from conversejs import xmpp from conversejs.models import XMPPAccount @@ -22,7 +25,7 @@ from haystack.query import SearchQuerySet from colab.super_archives.models import (EmailAddress, Message, EmailAddressValidation) -from colab.search.utils import trans +from colab.search.utils import trans, getCollaborationData # from proxy.trac.models import WikiCollabCount, TicketCollabCount from .forms import (UserCreationForm, UserForm, ListsForm, UserUpdateForm, ChangeXMPPPasswordForm) @@ -71,48 +74,19 @@ class UserProfileDetailView(UserProfileBaseMixin, DetailView): count_types = OrderedDict() - fields_or_lookup = ( - {'collaborators__contains': user.username}, - {'fullname_and_username__contains': user.username}, - ) + # TODO: remove when mailman becomes a proxied plugin + messages = Message.objects.filter(from_address__user__pk=user.pk) + count_types[trans('thread')] = messages.count() - counter_class = {} - # { - # 'wiki': WikiCollabCount, - # 'ticket': TicketCollabCount, - # } + collaborations, count_types_extras = getCollaborationData(user) + collaborations.extend(messages) - types = ['thread'] - # types.extend(['ticket', 'wiki', 'changeset', 'attachment']) + collaborations = sorted(collaborations, key=lambda elem : elem.modified, reverse=True) - messages = Message.objects.filter(from_address__user__pk=user.pk) - for type in types: - CounterClass = counter_class.get(type) - if CounterClass: - try: - counter = CounterClass.objects.get(author=user.username) - except CounterClass.DoesNotExist: - count_types[trans(type)] = 0 - else: - count_types[trans(type)] = counter.count - elif type == 'thread': - count_types[trans(type)] = messages.count() - else: - sqs = SearchQuerySet() - for filter_or in fields_or_lookup: - sqs = sqs.filter_or(type=type, **filter_or) - count_types[trans(type)] = sqs.count() + count_types.update(count_types_extras) context['type_count'] = count_types - - sqs = SearchQuerySet() - for filter_or in fields_or_lookup: - sqs = sqs.filter_or(**filter_or).exclude(type='thread') - - try: - context['results'] = sqs.order_by('-modified', '-created')[:10] - except SearchBackendError: - context['results'] = sqs.order_by('-modified')[:10] + context['results'] = collaborations[:10] email_pks = [addr.pk for addr in user.emails.iterator()] query = Message.objects.filter(from_address__in=email_pks) @@ -127,7 +101,6 @@ class UserProfileDetailView(UserProfileBaseMixin, DetailView): context.update(kwargs) return super(UserProfileDetailView, self).get_context_data(**context) - def signup(request): BROWSERID_ENABLED = getattr(settings, 'BROWSERID_ENABLED', False) diff --git a/colab/home/views.py b/colab/home/views.py index 832048a..90cd32a 100644 --- a/colab/home/views.py +++ b/colab/home/views.py @@ -1,4 +1,3 @@ - from collections import OrderedDict from django.conf import settings @@ -8,53 +7,49 @@ from django.http import HttpResponse, Http404 from haystack.query import SearchQuerySet +<<<<<<< HEAD # from proxy.trac.models import WikiCollabCount, TicketCollabCount from colab.search.utils import trans from colab.super_archives.models import Thread +======= +from colab.search.utils import trans, getCollaborationData +from colab.super_archives.models import Thread, Message +from colab.search.preview_block import PreviewBlock +from colab.accounts.models import User +>>>>>>> Remove haystack search from dashboard an profile def dashboard(request): """Dashboard page""" + latest_threads = Thread.objects.all()[:6] - hottest_threads = Thread.highest_score.from_haystack()[:6] - - count_types = cache.get('home_chart') - if count_types is None: - count_types = OrderedDict() - count_types['thread'] = SearchQuerySet().filter( - type='thread', - ).count() - # TODO: this section should be inside trac app and only use it here - # if settings.TRAC_ENABLED: - # for type in ['changeset', 'attachment']: - # count_types[type] = SearchQuerySet().filter( - # type=type, - # ).count() - - # count_types['ticket'] = sum([ - # ticket.count for ticket in TicketCollabCount.objects.all() - # ]) - - # count_types['wiki'] = sum([ - # wiki.count for wiki in WikiCollabCount.objects.all() - # ]) - - cache.set('home_chart', count_types) + highest_score_threads = Thread.highest_score.all()[:6] + + hottest_threads = [] + for thread in highest_score_threads: + hottest_threads.append(thread.latest_message) + + latest_results, count_types = getCollaborationData() + threads = Thread.objects.all() + messages = [] + for t in threads: + messages.append(t.latest_message) + + latest_results.extend(messages) + latest_results = sorted(latest_results, + key=lambda elem : elem.modified, reverse=True) for key in count_types.keys(): count_types[trans(key)] = count_types.pop(key) context = { 'hottest_threads': hottest_threads[:6], - 'latest_threads': latest_threads, + 'latest_threads': latest_threads[:6], 'type_count': count_types, - 'latest_results': SearchQuerySet().all().order_by( - '-modified', '-created' - )[:6], + 'latest_results': latest_results[:6], } return render(request, 'home.html', context) - def robots(request): if getattr(settings, 'ROBOTS_NOINDEX', False): return HttpResponse('User-agent: *\nDisallow: /', diff --git a/colab/proxy/gitlab/apps.py b/colab/proxy/gitlab/apps.py index 8719018..f92d3e9 100644 --- a/colab/proxy/gitlab/apps.py +++ b/colab/proxy/gitlab/apps.py @@ -3,8 +3,36 @@ from django.utils.translation import ugettext_lazy as _ from ..utils.apps import ColabProxiedAppConfig - class ProxyGitlabAppConfig(ColabProxiedAppConfig): + ''' + You can define a collaboration_models list to tell colab which + models and what values should be displayed as collaborations. + + See the example bellow: + + Field model refers to the model to be displayed. + Field model_verbose is the human name to be displayed in charts. + Field collaborator_username tells which user(username) is associated with this collaboration. + + The value of the hashes maps the attribute or method of the model to be put in those positions. + + collaboration_models = [ + { + 'model' : 'User', + 'model_verbose' : 'User', + 'tag' : '', + 'title' : 'username', + 'description' : 'get_full_name', + 'fullname' : '', + 'modified' : 'modified', + 'modified_by' : '', + 'modified_by_url' : '', + 'url' : '', + 'type' : '', + 'collaborator_username' : 'username', + }, + ] + ''' name = 'colab.proxy.gitlab' verbose_name = 'Gitlab Proxy' @@ -23,3 +51,5 @@ class ProxyGitlabAppConfig(ColabProxiedAppConfig): ), } + + collaboration_models = [] diff --git a/colab/proxy/jenkins/apps.py b/colab/proxy/jenkins/apps.py index 52acd2b..15e1817 100644 --- a/colab/proxy/jenkins/apps.py +++ b/colab/proxy/jenkins/apps.py @@ -14,3 +14,5 @@ class ProxyJenkinsAppConfig(ColabProxiedAppConfig): (_('Continuos Integration'), ''), ), } + + collaboration_models = [] diff --git a/colab/proxy/noosfero/apps.py b/colab/proxy/noosfero/apps.py index bb9e75f..2f0c3da 100644 --- a/colab/proxy/noosfero/apps.py +++ b/colab/proxy/noosfero/apps.py @@ -19,3 +19,5 @@ class ProxyNoosferoAppConfig(ColabProxiedAppConfig): (_('Control panel'), 'myprofile'), ), } + + collaboration_models = [] diff --git a/colab/proxy/redmine/apps.py b/colab/proxy/redmine/apps.py index 1076304..121dea2 100644 --- a/colab/proxy/redmine/apps.py +++ b/colab/proxy/redmine/apps.py @@ -5,3 +5,5 @@ from ..utils.apps import ColabProxiedAppConfig class ProxyRedmineAppConfig(ColabProxiedAppConfig): name = 'colab.proxy.redmine' verbose_name = 'Redmine Proxy' + + collaboration_models = [] diff --git a/colab/proxy/trac/apps.py b/colab/proxy/trac/apps.py index d54d8bb..e5ea130 100644 --- a/colab/proxy/trac/apps.py +++ b/colab/proxy/trac/apps.py @@ -22,3 +22,5 @@ class ProxyTracAppConfig(ColabProxiedAppConfig): (_('New Wiki Page'), 'wiki/WikiNewPage'), ), } + + collaboration_models = [] diff --git a/colab/search/preview_block.py b/colab/search/preview_block.py new file mode 100644 index 0000000..5876af0 --- /dev/null +++ b/colab/search/preview_block.py @@ -0,0 +1,15 @@ +class PreviewBlock(): + tag = None + title = None + description = None + fullname = None + modified = None + modified_by = None + url = None + type = None + modified_by_url = None + collaborator_username = None + + def __init__(self, **kwargs): + for key, value in kwargs.items(): + setattr(self, key, value) diff --git a/colab/search/templates/search/search-message-preview.html b/colab/search/templates/search/search-message-preview.html index e449429..2a905e6 100644 --- a/colab/search/templates/search/search-message-preview.html +++ b/colab/search/templates/search/search-message-preview.html @@ -11,7 +11,6 @@ - {{ result.title }} diff --git a/colab/search/utils.py b/colab/search/utils.py index 8372ee3..dfe28f4 100644 --- a/colab/search/utils.py +++ b/colab/search/utils.py @@ -1,5 +1,14 @@ +import importlib +import inspect +from collections import OrderedDict + +from django.core.cache import cache from django.utils.translation import ugettext as _ +from django.apps import apps +from django.conf import settings +from colab.super_archives.models import Thread, Message +from colab.search.preview_block import PreviewBlock def trans(key): @@ -11,4 +20,73 @@ def trans(key): 'attachment': _('Attachments'), } + app_names = settings.PROXIED_APPS.keys() + + for app_name in app_names: + collaboration_models = apps.get_app_config(app_name).collaboration_models + + for collaboration in collaboration_models: + module = importlib.import_module('colab.proxy.{}.models'.format(app_name)) + elements = eval("module." + collaboration['model']).objects.all() + translations[ collaboration['model'].lower() ] = collaboration['model_verbose'] + return translations.get(key, key) + +def getCollaborationData(filter_by_user = None): + + latest_results = [] + count_types = cache.get('home_chart') + populate_count_types = False + + if count_types is None: + populate_count_types = True + count_types = OrderedDict() + count_types['thread'] = Thread.objects.count() + + app_names = settings.PROXIED_APPS.keys() + + for app_name in app_names: + collaboration_models = apps.get_app_config(app_name).collaboration_models + + for collaboration in collaboration_models: + module = importlib.import_module('colab.proxy.{}.models'.format(app_name)) + elements = eval("module." + collaboration['model']).objects + + if filter_by_user: + dic = {} + dic[collaboration['collaborator_username']] = filter_by_user + elements = elements.filter(**dic) + else: + elements = elements.all() + + latest_results.extend(parsePreviewBlock(elements, collaboration)) + + if populate_count_types: + count_types[ collaboration['model'].lower() ] = elements.count() + + if populate_count_types: + cache.set('home_chart', count_types) + + for key in count_types.keys(): + count_types[trans(key)] = count_types.pop(key) + + return latest_results, count_types + +def parsePreviewBlock(elements, collaboration): + results = [] + for element in elements: + previewblock = PreviewBlock() + attributes = collaboration.keys() + + for keyname in attributes: + if keyname == 'model' or keyname == 'model_verbose' or len(collaboration[keyname].strip()) == 0: + continue + value = getattr(element, collaboration[keyname]) + if(inspect.ismethod(value)): + setattr(previewblock, keyname, value() ) + else: + setattr(previewblock, keyname, value ) + + results.append(previewblock) + + return results \ No newline at end of file -- libgit2 0.21.2