Exemplo n.º 1
0
def test_searchNoDuplicate():
    result = apiHelper.searchGooglePlay('youtube')
    assert len(result) > 0, "Failed to find any match for keyword 'youtube'."
    duplicates = [(item, count) for item, count in Counter(result).items()
                  if count > 1]
    if len(duplicates):
        pytest.fail(
            f'view.searchGooglePlay returns duplicate results: {duplicates}',
            False)
Exemplo n.º 2
0
def search(request: django.http.HttpRequest):
    # If the user loads Google Analysis, let Nginx handle rating limit.
    if not request.COOKIES.get('_gaload') and limitRate(getClientIP(request)):
        return JsonResponse({'error': 'Rate limit reached. Wait 60 seconds.'})

    keyword = request.GET.get('q', '').strip()
    with connection.cursor() as cursor:
        try:
            logSearch(cursor, keyword, request)
        except django.db.utils.OperationalError:
            cursor.execute(apiHelper.getSqlCreateTableSearch())
            try:
                logSearch(cursor, keyword, request)
            except Exception as e:
                print(str(e))

    excludedPIds = [
        int(n) for n in request.GET.get('pids', '').split(',') if n != ''
    ]

    excludedCIds = [
        int(n) for n in request.GET.get('cids', '').split(',') if n != ''
    ]

    try:
        appAccessor = AppAccessor()
        appInfos = appAccessor.searchApps(keyword)

        needCompleteInfo = determineAppInfoCompleteness(request)

        if needCompleteInfo:
            appInfos = getCompleteAppInfo([a['id'] for a in appInfos])

        appInfos = filterApps(appInfos, excludedCIds, excludedPIds, request)

        # If we cannot find 200 matches from our database, we try to find more matches from Google.
        if len(appInfos) < 200 and cache.get('searchkey-' + keyword) is None:
            cache.set('searchkey-' + keyword, '', timeout=60 *
                      5)  # do not search the same keyword in 5 minutes
            appInfos2 = apiHelper.searchGooglePlay(keyword)
            if needCompleteInfo:
                appInfos2 = getCompleteAppInfo([a['id'] for a in appInfos2])

            appInfos2 = filterApps(appInfos2, excludedCIds, excludedPIds,
                                   request)

            appInfoIds = {a['id'] for a in appInfos}
            appInfos.extend(
                [a for a in appInfos2 if a['id'] not in appInfoIds])

        sortType = request.GET.get('sort')
        if sortType == 'rlh':  # rating low to high
            appInfos = sorted(appInfos, key=lambda a: a['rating'])
        elif sortType == 'rhl':  # rating high to low
            appInfos = sorted(appInfos,
                              key=lambda a: a['rating'],
                              reverse=True)
        elif sortType == 'plh':  # number of permissions low to high
            appInfos = sorted(appInfos, key=lambda a: len(a['permissions']))
        elif sortType == 'phl':  # number of permissions low to high
            appInfos = sorted(appInfos,
                              key=lambda a: len(a['permissions']),
                              reverse=True)

        response = JsonResponse({'apps': [dict(a) for a in appInfos]},
                                safe=False)
        response['Cache-Control'] = "public, max-age=3600"
        return response
    except requests.exceptions.SSLError as e:
        # In getCompleteAppInfo, we throw our own SSLError where we don't have request object.
        if e.request:
            url = urlparse(e.request.url)
            return JsonResponse({
                'error':
                f'Searching is aborted because secure connection to https://{url.netloc} is compromised.\nAttacker is attacking us, but we didn\'t leak your data!'
            })
        else:
            return JsonResponse({
                'error':
                f'Searching is aborted because secure connection is compromised.\nAttacker is attacking us, but we didn\'t leak your data!'
            })
Exemplo n.º 3
0
def test_searchKeywordEscpaing():
	result = apiHelper.searchGooglePlay('calculator&type=racing')
	assert any('racing'.casefold() in app['name'].casefold() for app in result), '"calculator&type=racing" should be considered as a single keyword. Results matching racing are expected.'