Mercurial > hg > bts-webui
view bts_webui/amancay/search.py @ 120:cfe047d5534a draft
Fix the javascript
author | marga |
---|---|
date | Tue, 28 Jul 2009 22:41:16 +0000 |
parents | 912072a83ed4 |
children | 25e9f39aadd4 |
line wrap: on
line source
import datetime import math, time import threading # Needed to get_template, prepare context and output Response from django.template import Context, loader from django.http import HttpResponse, HttpResponseRedirect # Shortcut for rendering a response from django.shortcuts import get_object_or_404, render_to_response # Model clases from django.contrib.auth.models import User from bts_webui.amancay.models import Package from django.contrib.sites.models import Site # Needed for AJAX from django.utils import simplejson # Manage the sessions myself from django.contrib.sessions.models import Session # Needed for SOAP from bts_queries import SoapQueries queries = SoapQueries() # Bug views def search(request): """ View: render the bug table resulting from the current search. """ user = request.user amount = 20 # TODO: get this amount from user prefs # Get the page page = request.GET.get('page') try: page = int(page) page -= 1 except: page = 0 # Perform the query package = request.GET.get('package_search') if package: search_id = 'package:%s' % package bug_list = retrieve_search(request, search_id, amount, page) if bug_list is None: bugs = queries.get_all_packages_bugs(package) bugs.sort(reverse=True) bug_list = get_bugs_status(request, search_id, bugs, amount, page) total = len(bugs) else: total = request.session['searches'][search_id]['total'] pages = int(math.ceil(total/(amount*1.0))) return render_bug_table(request, 'Latest bugs for %s' % package, bug_list, page+1, pages, total, 'package_search') else: return render_bug_table(request, '', None, 0, 0, 0, 'search') def get_bugs_status(request, search_id, bugs, amount, page): """ Gets the status for the bugs in the provided list, returns such list. """ if bugs: start = page * amount bug_list = queries.get_bugs_status(bugs[start:start+amount]) store_search(request, search_id, bug_list, total=len(bugs)) bug_list.sort(key=lambda x: x.log_modified, reverse=True) # Start the read-ahead thread reader = _ReadAhead(request, search_id, bugs, amount) reader.start() else: bug_list = None return bug_list def store_search(request, search_id, bug_list, append=False, last_page=0, total=0): """ Stores a search into the search db, which is serving now as a preloader. """ searches = request.session.get('searches') if searches is None: request.session['searches'] = {} searches = request.session['searches'] if not searches.has_key(search_id): searches[search_id] = {} searches[search_id]['stamp'] = time.time() searches[search_id]['last_page'] = last_page if total: searches[search_id]['total'] = total if append: if not searches[search_id].has_key('bugs'): searches[search_id]['bugs'] = [] else: searches[search_id]['bugs'] = [] searches[search_id]['bugs'].extend(bug_list) def retrieve_search(request, search_id, amount, page=0): """ Return a queued search. """ searches = request.session.get('searches') if searches is not None: if searches.has_key(search_id): if (time.time() - searches[search_id]['stamp']) < 900: start = page * amount searches[search_id]['last_page'] = 0 return searches[search_id]['bugs'][start:start+amount] return None def render_bug_table(request, title, bug_list, page, num_pages, total, current_view): """ Render an individual bug table. """ # Calculate the pages start = page - 5 # FIXME: use django pager here if start < 1: start = 1 end = page + 5 if end > num_pages: end = num_pages pages = range(start, end+1) # URL for future searches url = 'http://%s/search/?%s=%s' % (Site.objects.get_current().domain, current_view, request.GET.get(current_view)) if request.GET.has_key('xhr'): # We only need to list the data. return HttpResponse(simplejson.dumps(bug_list), mimetype='application/javascript') elif request.path.find('table') != -1: # We only need to render the table return render_to_response('table.html', {'bug_list': bug_list, 'current_view': current_view, 'url': url, 'total_bugs': total, 'current_page': page, 'pages': pages}, ) else: # We need to render the whole page return render_to_response('search.html', {'bug_list': bug_list, 'current_view': current_view, 'url': url, 'total_bugs': total, 'current_user': request.user, 'current_page': page, 'pages': pages}, ) class _ReadAhead(threading.Thread): """ ReadAhead class used to preload bug lists. """ # FIXME: what does this do precisely? # FIXME: what about a cache? def __init__(self, request, search_id, bugs, amount): threading.Thread.__init__(self) self.request = request self.bugs = bugs self.amount = amount self.search_id = search_id def run(self): """ Start the ReadAhead thread. """ start = self.amount old_session = Session.objects.get(pk=self.request.session.session_key) bug_number = len(self.bugs) while start < bug_number: bug_list = queries.get_bugs_status(self.bugs[start:start+self.amount]) store_search(self.request, self.search_id, bug_list, True) start += self.amount # FIXME: Ugly hack to make the session save Session.objects.save(self.request.session.session_key, self.request.session._session, old_session.expire_date)