def movieSearch(request, page=1): from django.core.paginator import Paginator try: q = request.GET['q'] # april fools queries if datetime.now().day == 1 and datetime.now().month == 4: from aprilfools.views import resultcaller q = resultcaller() searchstring = q for char in escape_chars: # get rid of the bullshit q = q.replace(char, escape_chars[char]) except KeyError: q = "" try: if request.GET['optionsUp'] == "1": optionsUp = "1" else: optionsUp = "0" except KeyError: optionsUp = "0" try: page = int(page) - 1 if int(page) > 1 else 0 except Exception: page = 0 paramList = [ 'genre', 'cert', 'order', ] # list comprehensions for the winnnn genres = [x.name for x in MovieGenre.objects.all()] certs = [x.cert for x in MovieCert.objects.all()] allowedOrders = [ 'none', 'name', '-name', 'dateadded', '-dateadded', 'rating', '-rating', 'popularity', '-popularity', 'runtime', '-runtime' ] ALLOWED_VALUES = { 'genre': genres, 'cert': certs, 'order': allowedOrders, } defaults = { 'genre': 'all', 'cert': 'all', 'order': 'none', } params = {} # fill in params from GET for param in paramList: try: if request.GET[param] in ALLOWED_VALUES[ param] and request.GET[param] != "": params.update({param: request.GET[param]}) else: params.update({param: defaults[param]}) except KeyError: # some options weren't chosen - we set them here. params.update({param: defaults[param]}) # don't search movies without files - these will get cleared out of database later movieList = Movie.objects.all() if q != "": movieList = movieList.filter(name__icontains=q) if params['genre'] != 'all': movieList = movieList.filter(genres__name=params['genre']) if params['cert'] != 'all': movieList = movieList.filter(cert__cert=params['cert']) if params['order'] != 'none': movieList = movieList.order_by( params['order'], params['order'] if params['order'][0] != '-' else params['order'][1:]) try: optionsUp = '1' if request.GET['optionsUp'] == '1' else '0' except KeyError: optionsUp = '0' p = Paginator( movieList.annotate(num_files=Count('files')).filter(num_files__gte=1), PERPAGE_MOV) ############################################################## # ---- Log results of the search ---- # # try: client = request.META['HTTP_X_FORWARDED_FOR'] except KeyError: # REMOTE_ADDR is *always* 127.0.0.1 # unless we're on test server! client = request.META['REMOTE_ADDR'] newest = Log(time=time.mktime(time.localtime()), client=client, hits=p.count, position=page * PERPAGE_MOV, searchstring=u"Search [MOVIE]: {}".format(q)) newest.save() ###################################################### return render_to_response( 'advancedsearch/movies/results.html', { 'search': 'current', 'movies': 'current', 'genres': MovieGenre.objects.all(), 'certs': MovieCert.objects.all(), 'optionsUp': optionsUp, 'q': q, 'object_list': p.page(page + 1).object_list, 'page': p.page(page + 1), 'paginator': p, 'params': params, })
def results(request,page='1'): """ Returns the formatted results of a search. Arguments: Page (optional) An int or string, denoting which page of results to show (0-indexed) Template: :template:`search/results` Context: title 'M2M - Results: page {{page}}' search marks nav tab as 'current' q query string filesfound list of :model:`search.File` words list of the space-separated elements of {{q}}, used in :filter:`search_extras-highlight` params Keys: type Which types of files were searched, by fileending mode Which index(es) got searched order How the results are to be sorted useip This is not used anywhere. optionsUp A boolean, telling whether the options buttons are shown test Debugging variable page Current page number of results(1-indexed) prev previous page number of results (1-indexed) next Next page number of results (1-indexed) paginator A list of page numbers to show in the page links debug A dict of debugging stuff fileErrors An int counting the number of rows that couldn't be pulled out of the database errorids The id's of the :model:`search.File` s which caused errors time Time it took to complete the search, in seconds total Total number of files found, up to :setting:`SPH_MAX_RESULTS` mode Shortcut to params['mode'] """ ''' Handling some initial errors ''' escape_chars = { '!':r'\!', '<':r'\<', '>':r'\>', # '(':r'\(', # this is an operator for something # ')':r'\)', # this is an operator for something # '@':r'\@', # this is an operator for something '~':r'\~', "'":r'\'', '"':r'\"', '\\':r"", '/' : r'\/', #'$':r'$', '%':"", '#':'', #'^':'%%5E', # this is an operator for something #'-':r'\-', # this is an operator for something #r'|':"%%7F", # this is an operator for something } try: q = request.GET['q'] # april fools queries if datetime.now().day == 1 and datetime.now().month==4: from aprilfools.views import resultcaller q = resultcaller() searchstring = q for char in escape_chars: # get rid of the bullshit q = q.replace(char,escape_chars[char]) # the old m2m did some buttfuckery on the string, # but for no reason that i can see, aside from historical: # it ran a finite automata, to differentiate between # quotes'd search terms and un-quots'd; as far as i can tell # it no longer actually used this functionality. except KeyError: q = "" # regardless, this counts as a query for stat purposes # but do NOT create a new row. just update the current one. latestStat = Status.objects.all().order_by("-id")[0] latestStat.queries += 1 latestStat.save() try: if request.GET['optionsUp'] == "1": optionsUp = "1" else: optionsUp="0" except KeyError: optionsUp = "0" try: page = int(page) - 1 except Exception: page = 0 ''' Declarations, extendable where possible ''' paramList = [ 'type', 'mode', 'order', 'useip', ] allowedTypes = ['none','video','audio','text','software','images',] allowedModes = ['dirsSubstr','filesSubstr','filesdirsSubstr',] allowedOrders = ['none','FileSize', '-FileSize', 'Name', '-Name', 'DateAdded','-DateAdded','HostName','-HostName',] ALLOWED_VALUES = { 'type': allowedTypes, 'mode': allowedModes, 'order': allowedOrders, 'useip':[1,0], } defaults = { 'type':'none', 'mode':'filesdirsSubstr', 'order':'none', 'useip':0, } params = {} # fill search params, by hook or by crook for param in paramList: try: if request.GET[param] in ALLOWED_VALUES[param] and request.GET[param] != "": # empty arguments become the default. params.update({param:request.GET[param]}) else: params.update({param:defaults[param]}) except KeyError: # unset params get the default too params.update({param:defaults[param]}) # set the index and the appropriate model for later if params['mode']=="filesSubstr": indexing ='files' model = File elif params['mode']=='dirsSubstr': indexing='directories' model = Path else: indexing='filesdirs' model = File # type of file not specified? or searching directories if params['type'] == 'none' or indexing == 'directories': moding = SPH_MATCH_EXTENDED q2 = q params['type'] = 'none' else: # figure out the type moding = SPH_MATCH_EXTENDED2 typeSpec = allowedTypes.index(params['type']) # type specified -> dirs are not type. indexing = 'files' # now 'switch' through them: # N.B. -- these indices are on line ~100 # because of the way we dealt with params early on, it should always be one of # these, or 'none', in which case it never sees this block anyway. if typeSpec == 1: # video endings = File.videoEndings elif typeSpec == 2: # audio endings= File.audioEndings elif typeSpec == 3: # text endings = File.textEndings elif typeSpec == 4: #images endings = File.imageEndings else: endings = "" # The @ makes it a filter for sphinx q2 = q + " @filenameend ("+endings+") " # sort order if params['order'] == 'none': sorting = SPH_SORT_RELEVANCE sortby = "" else: sizeSpec = allowedOrders.index(params['order']) # switch through if sizeSpec == 1: # filesize, asc sorting = SPH_SORT_ATTR_ASC sortby = "FileSize" elif sizeSpec == 2: # filesize, desc sorting = SPH_SORT_ATTR_DESC sortby = "FileSize" elif sizeSpec == 3: # name, asc sorting = SPH_SORT_ATTR_ASC sortby = "Name" elif sizeSpec == 4: # name, desc sorting = SPH_SORT_ATTR_DESC sortby = "Name" elif sizeSpec == 5: # dateadded, asc sorting = SPH_SORT_ATTR_ASC sortby = "DateAdded" elif sizeSpec == 6: # dateadded, desc sorting = SPH_SORT_ATTR_DESC sortby = "DateAdded" elif sizeSpec == 7: #hostname, asc sorting = SPH_SORT_ATTR_ASC sortby = "HostName" elif sizeSpec == 8: #hostname, desc sorting = SPH_SORT_ATTR_ASC sortby = "HostName" if q2 == "" and sortby == "" and params['type'] == 'none': sorting = SPH_SORT_ATTR_DESC sortby = "DateAdded" params['order'] = '-DateAdded' # create client instances, filling in required attrs client = SphinxClient() client.SetServer('laview.st.hmc.edu',9312) client.SetMatchMode(moding) client.SetSortMode(sorting,sortby) # this pre-slices the results: client.SetLimits(page*PERPAGE,PERPAGE,maxmatches=5000) client.SetFilter("isdeleted",[0]) client.SetFieldWeights({'FileName':2,'FullName':1}) # try to search; if there's an error, escape and print the error try: result = client.Query(q2,indexing) while True: multiplier = page fileErrors = 0 errorids = [] # if no matches, no need to waste time on other things if result['total'] < 1: break resultants = result['matches'] #populate a list with appropriate Files filesFound = [] escapeLoop = False for fileThing in resultants: # N.B. -- we have to 'try' this, because sometimes the sphinx indices have # records that no longer exist in the actual database. try: filesFound += [File.objects.get(pk=fileThing['id'])] except: try: filesFound += [Path.objects.get(pk=fileThing['id'])] except: # count the error hits fileErrors += 1 errorids += [fileThing['id']] # something wierd happened - lots of errors if len(filesFound) < 1: multiplier += 1 client.SetLimits(PERPAGE*multiplier,PERPAGE,maxmatches=5000) result = client.Query(q2, indexing) #got results! else: break try: filesFound except: filesFound=[] if len(filesFound) > 0: # Substring Highlighting wordsToLight = [] for entry in result['words']: wordsToLight += [entry['word']] else: wordsToLight = [] # N.B -- this block will hide the highlighting, if it's after the 40th character. for filerecord in filesFound: # as bryce says, f**k long path names with a stick: try: filerecord.oldname = filerecord.filename if len(filerecord.filename)>80: filerecord.filename= filerecord.filename[0:35]+" [...] "+filerecord.filename[-40:] except AttributeError: filerecord.oldname = filerecord.fullname if len(filerecord.fullname)>80: filerecord.fullname = filerecord.fullname[0:35]+" [...]"+filerecord.fullname[-40:] #---- # for use in the template #---- # this block renders as ' PREV 1 2 3 4 5...NEXT ' if result['total'] > PERPAGE: if int(page) > 6: paginator = range( max(1,int(page)-5),# either start at 1 or 5 less than # current page min(result['total']/50,int(page)+5) # go til either the # last page or 5 # more than the # current one ) else: if result['total'] % PERPAGE > 0: remainder = 1 else: remainder = 0 paginator = range(1,min((result['total']/PERPAGE+remainder+1),11)) if page == 0 or page == 1: prev = 1 else: prev = page - 1 if page == max(paginator) - 1: next = page else: next = page + 2 else: paginator = 1 prev = 1 next = 1 # In case no results were found, we need to set these to something # to avoid a NameError exception when the template loads. try: paginator except: paginator = 0 prev = 1 next = 1 ############################################################## # ---- Log results of the search ---- # # # for compatibility with old shit logMode = { 'none':1, 'audio':2, 'video':3, 'software':4, 'text':5, 'images':6, } logType = { 'filesSubstr':1, 'dirsSubstr':2, 'filesdirsSubstr':3, } # one day, this block will actually check if key exists, # rather than try/excepting it like a dirty migrant worker. try: client = request.META['HTTP_X_FORWARDED_FOR'] except KeyError: # REMOTE_ADDR is *always* 127.0.0.1 # unless we're on test server! client = request.META['REMOTE_ADDR'] from stats.models import Log newest = Log(time=time.mktime(time.localtime()), client=client, found=result['total'], position=int(page)*PERPAGE, searchstring="Search: {}".format(q), mode=logType[params['mode']], flags=logMode[params['type']], hosttype=3) newest.save() ###################################################### try: fileErrors except: fileErrors = 0 return render_to_response('search/results.html', { 'title':'M2M - Results: page '+str(page+1), 'search':'current', 'files':'current', 'q': searchstring, #so it displays all pretty-like 'filesfound':filesFound, #'searchmeta':searchMeta, 'words':wordsToLight, 'params':params, 'optionsUp':optionsUp, 'test':test, 'page':int(page)+1, 'prev':prev, 'next':next, 'paginator':paginator, 'debug':DEBUG, 'fileErrors':fileErrors, 'errorids' : errorids, 'time': result['time'], 'total': result['total'], 'mode': params['mode'], }) except Exception, e: # you should know what's up by now. # if not, try: if client.GetLastError(): error = "Query Failed: %(error)s"%{'error':client.GetLastError()} else: error = "Something went wrong; Please change your search terms! \ %s" % e except AttributeError: error = "Well, shit; I don't know. Probably we don't have %s" % q return render_to_response('search/results.html', { 'title': "M2M - Resu-no, shit. What?", 'q':q, 'error':error, 'mode':params['mode'], 'optionsUp':optionsUp, 'page': 'WTF', },)
def musicSearch(request): ''' Wrapper for the more detailed searching required by the nature of music searching. ''' from urllib import urlencode ############################################################## # ---- Log results of the search ---- # # try: client = request.META['HTTP_X_FORWARDED_FOR'] except KeyError: # REMOTE_ADDR is *always* 127.0.0.1 # unless we're on test server! client = request.META['REMOTE_ADDR'] newest = Log(time=time.mktime(time.localtime()), client=client, searchstring=u"Search [MUSIC]: {}".format(request.GET['q'])) newest.save() ###################################################### # hand these off to helper methods - which we have so that you can # page through each set of results individually, via AJAX #songset = musicSearch_Song(q) #albumset = musicSearch_album(q) #artistset = musicSearch_artist(q) paramList = [ 'genre', 'order', 'type', ] genres = [x.name for x in MusicGenre.objects.all()] allowedTypes = ['Song', 'Album', 'Artist'] allowedOrders = [ 'none', 'name', '-name', 'dateadded', '-dateadded', 'rating', '-rating', 'popularity', '-popularity', 'runtime', '-runtime' ] ALLOWED_VALUES = { 'genre': genres, 'order': allowedOrders, 'type': allowedTypes, } defaults = { 'genre': 'all', 'order': 'none', 'type': 'all', } params = {} # fill in params from GET for param in paramList: try: if request.GET[param] in ALLOWED_VALUES[ param] and request.GET[param] != "": params.update({param: request.GET[param]}) else: params.update({param: defaults[param]}) except KeyError: # some options weren't chosen - we set them here. params.update({param: defaults[param]}) try: optionsUp = '1' if request.GET['optionsUp'] == '1' else '0' except KeyError: optionsUp = '0' return render_to_response( 'advancedsearch/music/results.html', { 'search': 'current', 'music': 'current', 'genres': MusicGenre.objects.all(), 'q': request.GET['q'], 'params': params, 'urlparams': urlencode(params), 'optionsUp': optionsUp, })
def movieSearch(request, page=1): from django.core.paginator import Paginator try: q = request.GET["q"] # april fools queries if datetime.now().day == 1 and datetime.now().month == 4: from aprilfools.views import resultcaller q = resultcaller() searchstring = q for char in escape_chars: # get rid of the bullshit q = q.replace(char, escape_chars[char]) except KeyError: q = "" try: if request.GET["optionsUp"] == "1": optionsUp = "1" else: optionsUp = "0" except KeyError: optionsUp = "0" try: page = int(page) - 1 if int(page) > 1 else 0 except Exception: page = 0 paramList = ["genre", "cert", "order"] # list comprehensions for the winnnn genres = [x.name for x in MovieGenre.objects.all()] certs = [x.cert for x in MovieCert.objects.all()] allowedOrders = [ "none", "name", "-name", "dateadded", "-dateadded", "rating", "-rating", "popularity", "-popularity", "runtime", "-runtime", ] ALLOWED_VALUES = {"genre": genres, "cert": certs, "order": allowedOrders} defaults = {"genre": "all", "cert": "all", "order": "none"} params = {} # fill in params from GET for param in paramList: try: if request.GET[param] in ALLOWED_VALUES[param] and request.GET[param] != "": params.update({param: request.GET[param]}) else: params.update({param: defaults[param]}) except KeyError: # some options weren't chosen - we set them here. params.update({param: defaults[param]}) # don't search movies without files - these will get cleared out of database later movieList = Movie.objects.all() if q != "": movieList = movieList.filter(name__icontains=q) if params["genre"] != "all": movieList = movieList.filter(genres__name=params["genre"]) if params["cert"] != "all": movieList = movieList.filter(cert__cert=params["cert"]) if params["order"] != "none": movieList = movieList.order_by( params["order"], params["order"] if params["order"][0] != "-" else params["order"][1:] ) try: optionsUp = "1" if request.GET["optionsUp"] == "1" else "0" except KeyError: optionsUp = "0" p = Paginator(movieList.annotate(num_files=Count("files")).filter(num_files__gte=1), PERPAGE_MOV) ############################################################## # ---- Log results of the search ---- # # try: client = request.META["HTTP_X_FORWARDED_FOR"] except KeyError: # REMOTE_ADDR is *always* 127.0.0.1 # unless we're on test server! client = request.META["REMOTE_ADDR"] newest = Log( time=time.mktime(time.localtime()), client=client, hits=p.count, position=page * PERPAGE_MOV, searchstring=u"Search [MOVIE]: {}".format(q), ) newest.save() ###################################################### return render_to_response( "advancedsearch/movies/results.html", { "search": "current", "movies": "current", "genres": MovieGenre.objects.all(), "certs": MovieCert.objects.all(), "optionsUp": optionsUp, "q": q, "object_list": p.page(page + 1).object_list, "page": p.page(page + 1), "paginator": p, "params": params, }, )
def musicSearch(request): """ Wrapper for the more detailed searching required by the nature of music searching. """ from urllib import urlencode ############################################################## # ---- Log results of the search ---- # # try: client = request.META["HTTP_X_FORWARDED_FOR"] except KeyError: # REMOTE_ADDR is *always* 127.0.0.1 # unless we're on test server! client = request.META["REMOTE_ADDR"] newest = Log( time=time.mktime(time.localtime()), client=client, searchstring=u"Search [MUSIC]: {}".format(request.GET["q"]) ) newest.save() ###################################################### # hand these off to helper methods - which we have so that you can # page through each set of results individually, via AJAX # songset = musicSearch_Song(q) # albumset = musicSearch_album(q) # artistset = musicSearch_artist(q) paramList = ["genre", "order", "type"] genres = [x.name for x in MusicGenre.objects.all()] allowedTypes = ["Song", "Album", "Artist"] allowedOrders = [ "none", "name", "-name", "dateadded", "-dateadded", "rating", "-rating", "popularity", "-popularity", "runtime", "-runtime", ] ALLOWED_VALUES = {"genre": genres, "order": allowedOrders, "type": allowedTypes} defaults = {"genre": "all", "order": "none", "type": "all"} params = {} # fill in params from GET for param in paramList: try: if request.GET[param] in ALLOWED_VALUES[param] and request.GET[param] != "": params.update({param: request.GET[param]}) else: params.update({param: defaults[param]}) except KeyError: # some options weren't chosen - we set them here. params.update({param: defaults[param]}) try: optionsUp = "1" if request.GET["optionsUp"] == "1" else "0" except KeyError: optionsUp = "0" return render_to_response( "advancedsearch/music/results.html", { "search": "current", "music": "current", "genres": MusicGenre.objects.all(), "q": request.GET["q"], "params": params, "urlparams": urlencode(params), "optionsUp": optionsUp, }, )
def say(self, message): self.send_rcon('"' + self.pad_with_spaces(message) + '"') Log(message=message).save()
def results(request, page='1'): """ Returns the formatted results of a search. Arguments: Page (optional) An int or string, denoting which page of results to show (0-indexed) Template: :template:`search/results` Context: title 'M2M - Results: page {{page}}' search marks nav tab as 'current' q query string filesfound list of :model:`search.File` words list of the space-separated elements of {{q}}, used in :filter:`search_extras-highlight` params Keys: type Which types of files were searched, by fileending mode Which index(es) got searched order How the results are to be sorted useip This is not used anywhere. optionsUp A boolean, telling whether the options buttons are shown test Debugging variable page Current page number of results(1-indexed) prev previous page number of results (1-indexed) next Next page number of results (1-indexed) paginator A list of page numbers to show in the page links debug A dict of debugging stuff fileErrors An int counting the number of rows that couldn't be pulled out of the database errorids The id's of the :model:`search.File` s which caused errors time Time it took to complete the search, in seconds total Total number of files found, up to :setting:`SPH_MAX_RESULTS` mode Shortcut to params['mode'] """ ''' Handling some initial errors ''' escape_chars = { '!': r'\!', '<': r'\<', '>': r'\>', # '(':r'\(', # this is an operator for something # ')':r'\)', # this is an operator for something # '@':r'\@', # this is an operator for something '~': r'\~', "'": r'\'', '"': r'\"', '\\': r"", '/': r'\/', #'$':r'$', '%': "", '#': '', #'^':'%%5E', # this is an operator for something #'-':r'\-', # this is an operator for something #r'|':"%%7F", # this is an operator for something } try: q = request.GET['q'] # april fools queries if datetime.now().day == 1 and datetime.now().month == 4: from aprilfools.views import resultcaller q = resultcaller() searchstring = q for char in escape_chars: # get rid of the bullshit q = q.replace(char, escape_chars[char]) # the old m2m did some buttfuckery on the string, # but for no reason that i can see, aside from historical: # it ran a finite automata, to differentiate between # quotes'd search terms and un-quots'd; as far as i can tell # it no longer actually used this functionality. except KeyError: q = "" # regardless, this counts as a query for stat purposes # but do NOT create a new row. just update the current one. latestStat = Status.objects.all().order_by("-id")[0] latestStat.queries += 1 latestStat.save() try: if request.GET['optionsUp'] == "1": optionsUp = "1" else: optionsUp = "0" except KeyError: optionsUp = "0" try: page = int(page) - 1 except Exception: page = 0 ''' Declarations, extendable where possible ''' paramList = [ 'type', 'mode', 'order', 'useip', ] allowedTypes = [ 'none', 'video', 'audio', 'text', 'software', 'images', ] allowedModes = [ 'dirsSubstr', 'filesSubstr', 'filesdirsSubstr', ] allowedOrders = [ 'none', 'FileSize', '-FileSize', 'Name', '-Name', 'DateAdded', '-DateAdded', 'HostName', '-HostName', ] ALLOWED_VALUES = { 'type': allowedTypes, 'mode': allowedModes, 'order': allowedOrders, 'useip': [1, 0], } defaults = { 'type': 'none', 'mode': 'filesdirsSubstr', 'order': 'none', 'useip': 0, } params = {} # fill search params, by hook or by crook for param in paramList: try: if request.GET[param] in ALLOWED_VALUES[ param] and request.GET[param] != "": # empty arguments become the default. params.update({param: request.GET[param]}) else: params.update({param: defaults[param]}) except KeyError: # unset params get the default too params.update({param: defaults[param]}) # set the index and the appropriate model for later if params['mode'] == "filesSubstr": indexing = 'files' model = File elif params['mode'] == 'dirsSubstr': indexing = 'directories' model = Path else: indexing = 'filesdirs' model = File # type of file not specified? or searching directories if params['type'] == 'none' or indexing == 'directories': moding = SPH_MATCH_EXTENDED q2 = q params['type'] = 'none' else: # figure out the type moding = SPH_MATCH_EXTENDED2 typeSpec = allowedTypes.index(params['type']) # type specified -> dirs are not type. indexing = 'files' # now 'switch' through them: # N.B. -- these indices are on line ~100 # because of the way we dealt with params early on, it should always be one of # these, or 'none', in which case it never sees this block anyway. if typeSpec == 1: # video endings = File.videoEndings elif typeSpec == 2: # audio endings = File.audioEndings elif typeSpec == 3: # text endings = File.textEndings elif typeSpec == 4: #images endings = File.imageEndings else: endings = "" # The @ makes it a filter for sphinx q2 = q + " @filenameend (" + endings + ") " # sort order if params['order'] == 'none': sorting = SPH_SORT_RELEVANCE sortby = "" else: sizeSpec = allowedOrders.index(params['order']) # switch through if sizeSpec == 1: # filesize, asc sorting = SPH_SORT_ATTR_ASC sortby = "FileSize" elif sizeSpec == 2: # filesize, desc sorting = SPH_SORT_ATTR_DESC sortby = "FileSize" elif sizeSpec == 3: # name, asc sorting = SPH_SORT_ATTR_ASC sortby = "Name" elif sizeSpec == 4: # name, desc sorting = SPH_SORT_ATTR_DESC sortby = "Name" elif sizeSpec == 5: # dateadded, asc sorting = SPH_SORT_ATTR_ASC sortby = "DateAdded" elif sizeSpec == 6: # dateadded, desc sorting = SPH_SORT_ATTR_DESC sortby = "DateAdded" elif sizeSpec == 7: #hostname, asc sorting = SPH_SORT_ATTR_ASC sortby = "HostName" elif sizeSpec == 8: #hostname, desc sorting = SPH_SORT_ATTR_ASC sortby = "HostName" if q2 == "" and sortby == "" and params['type'] == 'none': sorting = SPH_SORT_ATTR_DESC sortby = "DateAdded" params['order'] = '-DateAdded' # create client instances, filling in required attrs client = SphinxClient() client.SetServer('laview.st.hmc.edu', 9312) client.SetMatchMode(moding) client.SetSortMode(sorting, sortby) # this pre-slices the results: client.SetLimits(page * PERPAGE, PERPAGE, maxmatches=5000) client.SetFilter("isdeleted", [0]) client.SetFieldWeights({'FileName': 2, 'FullName': 1}) # try to search; if there's an error, escape and print the error try: result = client.Query(q2, indexing) while True: multiplier = page fileErrors = 0 errorids = [] # if no matches, no need to waste time on other things if result['total'] < 1: break resultants = result['matches'] #populate a list with appropriate Files filesFound = [] escapeLoop = False for fileThing in resultants: # N.B. -- we have to 'try' this, because sometimes the sphinx indices have # records that no longer exist in the actual database. try: filesFound += [File.objects.get(pk=fileThing['id'])] except: try: filesFound += [Path.objects.get(pk=fileThing['id'])] except: # count the error hits fileErrors += 1 errorids += [fileThing['id']] # something wierd happened - lots of errors if len(filesFound) < 1: multiplier += 1 client.SetLimits(PERPAGE * multiplier, PERPAGE, maxmatches=5000) result = client.Query(q2, indexing) #got results! else: break try: filesFound except: filesFound = [] if len(filesFound) > 0: # Substring Highlighting wordsToLight = [] for entry in result['words']: wordsToLight += [entry['word']] else: wordsToLight = [] # N.B -- this block will hide the highlighting, if it's after the 40th character. for filerecord in filesFound: # as bryce says, f**k long path names with a stick: try: filerecord.oldname = filerecord.filename if len(filerecord.filename) > 80: filerecord.filename = filerecord.filename[ 0:35] + " [...] " + filerecord.filename[-40:] except AttributeError: filerecord.oldname = filerecord.fullname if len(filerecord.fullname) > 80: filerecord.fullname = filerecord.fullname[ 0:35] + " [...]" + filerecord.fullname[-40:] #---- # for use in the template #---- # this block renders as ' PREV 1 2 3 4 5...NEXT ' if result['total'] > PERPAGE: if int(page) > 6: paginator = range( max(1, int(page) - 5), # either start at 1 or 5 less than # current page min(result['total'] / 50, int(page) + 5) # go til either the # last page or 5 # more than the # current one ) else: if result['total'] % PERPAGE > 0: remainder = 1 else: remainder = 0 paginator = range( 1, min((result['total'] / PERPAGE + remainder + 1), 11)) if page == 0 or page == 1: prev = 1 else: prev = page - 1 if page == max(paginator) - 1: next = page else: next = page + 2 else: paginator = 1 prev = 1 next = 1 # In case no results were found, we need to set these to something # to avoid a NameError exception when the template loads. try: paginator except: paginator = 0 prev = 1 next = 1 ############################################################## # ---- Log results of the search ---- # # # for compatibility with old shit logMode = { 'none': 1, 'audio': 2, 'video': 3, 'software': 4, 'text': 5, 'images': 6, } logType = { 'filesSubstr': 1, 'dirsSubstr': 2, 'filesdirsSubstr': 3, } # one day, this block will actually check if key exists, # rather than try/excepting it like a dirty migrant worker. try: client = request.META['HTTP_X_FORWARDED_FOR'] except KeyError: # REMOTE_ADDR is *always* 127.0.0.1 # unless we're on test server! client = request.META['REMOTE_ADDR'] from stats.models import Log newest = Log(time=time.mktime(time.localtime()), client=client, found=result['total'], position=int(page) * PERPAGE, searchstring="Search: {}".format(q), mode=logType[params['mode']], flags=logMode[params['type']], hosttype=3) newest.save() ###################################################### try: fileErrors except: fileErrors = 0 return render_to_response( 'search/results.html', { 'title': 'M2M - Results: page ' + str(page + 1), 'search': 'current', 'files': 'current', 'q': searchstring, #so it displays all pretty-like 'filesfound': filesFound, #'searchmeta':searchMeta, 'words': wordsToLight, 'params': params, 'optionsUp': optionsUp, 'test': test, 'page': int(page) + 1, 'prev': prev, 'next': next, 'paginator': paginator, 'debug': DEBUG, 'fileErrors': fileErrors, 'errorids': errorids, 'time': result['time'], 'total': result['total'], 'mode': params['mode'], }) except Exception, e: # you should know what's up by now. # if not, try: if client.GetLastError(): error = "Query Failed: %(error)s" % { 'error': client.GetLastError() } else: error = "Something went wrong; Please change your search terms! \ %s" % e except AttributeError: error = "Well, shit; I don't know. Probably we don't have %s" % q return render_to_response( 'search/results.html', { 'title': "M2M - Resu-no, shit. What?", 'q': q, 'error': error, 'mode': params['mode'], 'optionsUp': optionsUp, 'page': 'WTF', }, )