From 63b0fc6269b38edf7234b9f151b80d81f614c0a3 Mon Sep 17 00:00:00 2001 From: Filipp Lepalaan Date: Tue, 4 Aug 2015 10:11:24 +0300 Subject: Initial commit First public commit --- servo/views/search.py | 254 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 servo/views/search.py (limited to 'servo/views/search.py') diff --git a/servo/views/search.py b/servo/views/search.py new file mode 100644 index 0000000..c61eca6 --- /dev/null +++ b/servo/views/search.py @@ -0,0 +1,254 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2013, First Party Software +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: + +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. + +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +import re +import gsxws + +from django.db.models import Q +from django.core.cache import cache +from django.shortcuts import render, redirect +from django.utils.translation import ugettext as _ +from django.core.urlresolvers import reverse + +from django.http import QueryDict, HttpResponseRedirect + +from servo.models.note import Note +from servo.models.wiki import Article +from servo.models.device import Device +from servo.models.product import Product +from servo.models.common import GsxAccount +from servo.models.purchases import PurchaseOrder +from servo.models.order import Order, ServiceOrderItem + + +def results_redirect(view, data): + q = QueryDict('', mutable=True) + q['q'] = data['query'] + query_str = q.urlencode() + url = reverse(view, args=[data['what']]) + return HttpResponseRedirect("%s?%s" % (url, query_str)) + + +def prepare_result_view(request): + + query = request.GET.get('q') + + data = {'title': _('Search results for "%s"' % query)} + + data['gsx_type'] = gsxws.validate(query.upper()) + data['query'] = query + data['tag_id'] = None + data['cat_id'] = None # Product category + data['group'] = 'all' # customer group + + return data, query + + +def list_gsx(request, what="warranty"): + data, query = prepare_result_view(request) + data['what'] = what + return render(request, "search/results/gsx.html", data) + + +def search_gsx(request, what, arg, value): + if request.is_ajax(): + + if what == "parts" and value != "None": + results = [] + GsxAccount.default(user=request.user) + + try: + product = gsxws.Product(productName=value) + parts = product.parts() + for p in parts: + results.append(Product.from_gsx(p)) + except gsxws.GsxError, e: + data = {'message': e} + return render(request, "search/results/gsx_error.html", data) + + data = {'results': results} + + return render(request, "search/results/gsx_%s.html" % what, data) + + data = {arg: value} + return render(request, "search/gsx_results.html", data) + + +def view_gsx_results(request, what="warranty"): + """ + Searches for something from GSX. Defaults to warranty lookup. + GSX search strings are always UPPERCASE. + """ + results = list() + data, query = prepare_result_view(request) + query = query.upper() + + error_template = "search/results/gsx_error.html" + + if data['gsx_type'] == "dispatchId": + what = "repairs" + + if data['gsx_type'] == "partNumber": + what = "parts" + + data['what'] = what + gsx_type = data['gsx_type'] + + try: + if request.session.get("current_queue"): + queue = request.session['current_queue'] + GsxAccount.default(request.user, queue) + else: + GsxAccount.default(request.user) + except gsxws.GsxError, e: + error = {'message': e} + return render(request, error_template, error) + + if gsx_type == "serialNumber" or "alternateDeviceId": + try: + device = Device.objects.get(sn=query) + except Device.DoesNotExist: + device = Device(sn=query) + + if what == "warranty": + if cache.get(query): + result = cache.get(query) + else: + try: + result = Device.from_gsx(query) + except gsxws.GsxError, e: + error = {'message': e} + return render(request, error_template, error) + + if re.match(r'iPhone', result.description): + result.activation = device.get_activation() + + results.append(result) + + if what == "parts": + # looking for parts + if gsx_type == "partNumber": + # ... with a part number + part = gsxws.Part(partNumber=query) + + try: + partinfo = part.lookup() + except gsxws.GsxError, e: + error = {'message': e} + return render(request, error_template, error) + + product = Product.from_gsx(partinfo) + cache.set(query, product) + results.append(product) + else: + # ... with a serial number + try: + results = device.get_parts() + data['device'] = device + except Exception, e: + error = {'message': e} + return render(request, error_template, error) + + if what == "repairs": + # Looking for GSX repairs + if gsx_type == "serialNumber": + # ... with a serial number + try: + device = gsxws.Product(query) + results = device.repairs() + except gsxws.GsxError, e: + return render(request, "search/results/gsx_notfound.html") + + elif gsx_type == "dispatchId": + # ... with a repair confirmation number + repair = gsxws.Repair(number=query) + try: + results = repair.lookup() + except gsxws.GsxError, e: + error = {'message': e} + return render(request, error_template, error) + + if what == "repair_details": + repair = gsxws.Repair(number=query) + results = repair.details() + return render(request, "search/results/gsx_repair_details.html", results) + + # Cache the results for quicker access later + cache.set('%s-%s' % (what, query), results) + data['results'] = results + + return render(request, "search/results/gsx_%s.html" % what, data) + + +def list_products(request): + data, query = prepare_result_view(request) + data['products'] = Product.objects.filter( + Q(code__icontains=query) | Q(title__icontains=query) + ) + + return render(request, "search/results/products.html", data) + + +def list_notes(request): + data, query = prepare_result_view(request) + data['notes'] = Note.objects.filter(body__icontains=query) + return render(request, "search/results/notes.html", data) + + +def spotlight(request): + """ + Searches for anything and redirects to the "closest" result view. + GSX searches are done separately. + """ + data, query = prepare_result_view(request) + data['what'] = "warranty" + + if Order.objects.filter(customer__name__icontains=query).exists(): + return list_orders(request) + + if data['gsx_type'] == "serialNumber": + try: + device = Device.objects.get(sn=query) + return redirect(device) + except Device.DoesNotExist: + return results_redirect("search-gsx", data) + + data['parts'] = ServiceOrderItem.objects.filter(sn__icontains=query) + + if gsxws.validate(query, "dispatchId"): + try: + po = PurchaseOrder.objects.get(confirmation=query) + data['orders'] = [po.sales_order] + except PurchaseOrder.DoesNotExist: + pass + + data['products'] = Product.objects.filter( + Q(code__icontains=query) | Q(title__icontains=query) + ) + + data['articles'] = Article.objects.filter(content__contains=query) + + return render(request, "search/spotlight.html", data) -- cgit v1.2.3