예제 #1
0
파일: gallery.py 프로젝트: nickryand/Frog
def search(query, model):
    """ Performs a search query and returns the object ids """
    query = '%s*' % query.strip()
    LOGGER.debug(query)
    sqs = SearchQuerySet()
    sqs = sqs.filter(content=query).models(model)

    return [o.pk for o in sqs]
예제 #2
0
파일: gallery.py 프로젝트: nickryand/Frog
def _filter(request, object_, tags=None, models=(Image, Video), rng=None, more=False):
    """Filters Piece objects from self based on filters, search, and range

    :param tags: List of tag IDs to filter
    :type tags: list
    :param models: List of model classes to filter on
    :type models: list
    :param rng: Range of objects to return. i.e. 0:100
    :type rng: str
    :param more -- bool, Returns more of the same filtered set of images based on session range

    return list, Objects filtered
    """
    
    NOW = time.clock()

    res = Result()
    
    idDict = {}
    objDict = {}
    lastIDs = {}
    data = {}

    LOGGER.debug('init: %f' % (time.clock() - NOW))
    if request.user.is_anonymous():
        gRange = 300
    else:
        Prefs = json.loads(UserPref.objects.get(user=request.user).data)
        gRange = Prefs['batchSize']
    request.session.setdefault('frog_range', '0:%i' % gRange)

    if rng:
        s, e = [int(x) for x in rng.split(':')]
    else:
        if more:
            s = int(request.session.get('frog_range', '0:%i' % gRange).split(':')[1])
            e = s + gRange
            s, e = 0, gRange
        else:
            s, e = 0, gRange

    ## -- Gat all IDs for each model
    for m in models:
        indexes = list(m.model_class().objects.all().values_list('id', flat=True))
        if not indexes:
            continue

        lastIndex = indexes[0]
        if more:
            ## -- This is a request for more results
            idx = request.session.get('last_%s_id' % m.model, lastIndex + 1)
            lastIDs.setdefault('last_%s_id' % m.model, idx)
        else:
            lastIDs['last_%s_id' % m.model] = lastIndex + 1
        
        ## -- Start with objects within range
        idDict[m.model] = m.model_class().objects.filter(gallery=object_, id__lt=lastIDs['last_%s_id' % m.model])
        LOGGER.debug(m.model + '_initial_query: %f' % (time.clock() - NOW))

        if tags:
            for bucket in tags:
                searchQuery = ""
                o = None
                for item in bucket:
                    ## -- filter by tag
                    if isinstance(item, int) or isinstance(item, long):
                        if not o:
                            o = Q()
                        o |= Q(tags__id=item)
                    ## -- add to search string
                    else:
                        searchQuery += item + ' '
                        if not HAYSTACK:
                            if not o:
                                o = Q()
                            ## -- use a basic search
                            LOGGER.debug('search From LIKE')
                            o |= Q(title__icontains=item)
                if HAYSTACK and searchQuery != "":
                    ## -- once all tags have been filtered, filter by search
                    searchIDs = search(searchQuery, m.model_class())
                    if searchIDs:
                        if not o:
                            o = Q()
                        LOGGER.debug('searchFrom haystack:' + str(searchIDs))
                        o |= Q(id__in=searchIDs)

                if o:
                    ## -- apply the filters
                    idDict[m.model] = idDict[m.model].filter(o)
                else:
                    idDict[m.model] = idDict[m.model].none()

            LOGGER.debug(m.model + '_added_buckets(%i): %f' % (len(tags), time.clock() - NOW))
        
        ## -- Get all ids of filtered objects, this will be a very fast query
        idDict[m.model] = list(idDict[m.model].values_list('id', flat=True))
        LOGGER.debug(m.model + '_queried_ids: %f' % (time.clock() - NOW))

        res.message = str(s) + ':' + str(e)
        
        ## -- perform the main query to retrieve the objects we want
        objDict[m.model] = m.model_class().objects.filter(id__in=idDict[m.model]).select_related('author').prefetch_related('tags')
        if not rng:
            objDict[m.model] = objDict[m.model][:gRange]
        objDict[m.model] = list(objDict[m.model])
        LOGGER.debug(m.model + '_queried_obj: %f' % (time.clock() - NOW))
    
    
    ## -- combine and sort all objects by date
    objects = _sortObjects(**objDict) if len(models) > 1 else objDict.values()[0]
    objects = objects[s:e]
    LOGGER.debug('sorted: %f' % (time.clock() - NOW))

    ## -- serialize objects
    for i in objects:
        for m in models:
            if isinstance(i, m.model_class()):
                ## -- set the last ID per model for future lookups
                lastIDs['last_%s_id' % m.model] = i.id
                data['last_%s_id' % m.model] = i.id
        res.append(i.json())
    LOGGER.debug('serialized: %f' % (time.clock() - NOW))

    request.session['frog_range'] = ':'.join((str(s),str(e)))

    LOGGER.debug('total: %f' % (time.clock() - NOW))
    request.session['last_image_id'] = lastIDs.get('last_image_id', 0)
    request.session['last_video_id'] = lastIDs.get('last_video_id', 0)
    
    data['count'] = len(objects)
    data['queries'] = connection.queries

    res.value = data

    res.isSuccess = True

    return JsonResponse(res)