コード例 #1
0
ファイル: views.py プロジェクト: 350dotorg/akcrm
def _search2(request, query):
    querystring = query.query_string
    query_params = QueryDict(querystring)
    normalized = normalize_querystring(query_params)
    if normalized != querystring:
        raise NonNormalQuerystring(normalized)
    querystring = normalized

    report = sql.get_or_create_report(query.raw_sql, query.human_query, querystring,
                                      query.report_data)

    if report.status is None:
        method = settings.AKTIVATOR_REPORT_POLLING_METHOD
        assert method in ("synchronous", "celery", "thread", "cron")
        if method == "celery":
            from akcrm.search.tasks import poll_report
            poll_report.delay(report)
        elif method == "thread":
            import threading
            threading.Thread(target=report.poll_results).start()
        elif method == "synchronous":
            report.poll_results()
        elif method == "cron":
            raise NotImplementedError()

    return report
コード例 #2
0
ファイル: views.py プロジェクト: 350dotorg/akcrm
def build_query(querystring, queryset_modifier_fn=None):
    query_params = QueryDict(querystring)
    normalized = normalize_querystring(query_params)
    if normalized != querystring:
        raise NonNormalQuerystring(normalized)
    querystring = normalized

    base_user_query = CoreUser.objects.using("ak").order_by("id")
    
    includes = []

    include_pattern = re.compile("^include:\d+$")
    for key in query_params.keys():
        if (include_pattern.match(key)
            and query_params[key]
            and (not query_params[key].endswith('_istoggle'))):
            includes.append((key, query_params.getlist(key)))

    human_query = []

    all_user_queries = []
    for include_group in includes:
        users = base_user_query
        _human_query = []
        for item in include_group[1]:
            ## "distance" is handled in a group with "zipcode", so we ignore it here
            if item == "zipcode__distance":
                continue
            ## same for "contacted_by", in a group with "contacted_since"
            if item == "contacted_since__contacted_by":
                continue
            if item == "contacted_by__contacted_since":
                continue
            ## ditto
            if item == 'more_actions__since':
                continue

            possible_values = query_params.getlist(
                "%s_%s" % (include_group[0], item))
            if len(possible_values) == 0:
                continue
            query_data = QUERIES[item]
            extra_data = {}

            istogglename = '%s_%s_istoggle' % (include_group[0], item)
            istoggle = query_params.get(istogglename, '1')
            try:
                istoggle = bool(int(istoggle))
            except ValueError:
                istoggle = True
            extra_data['istoggle'] = istoggle

            ## XXX special cased zip code and distance
            # these two fields are together, if we have another case like this
            # we should probably formalize this
            if item == "zipcode":
                distance = query_params.get('%s_zipcode__distance' % include_group[0])
                if distance:
                    extra_data['distance'] = distance

            ## XXX special cased contacted_since and contacted_by
            # these two fields are together, if we have another case like this
            # we should probably formalize this
            if item == "contacted_since":
                contacted_by = query_params.get(
                    '%s_contacted_since__contacted_by' % include_group[0])
                if contacted_by:
                    extra_data['contacted_by'] = contacted_by

            if item == "contacted_by":
                contacted_since = query_params.get(
                    '%s_contacted_by__contacted_since' % include_group[0])
                if contacted_since:
                    extra_data['contacted_since'] = contacted_since

            if item == "emails_opened":
                since = query_params.get('%s_emails_opened__since' % include_group[0])
                if since:
                    extra_data['since'] = since
            if item == "more_actions":
                since = query_params.get('%s_more_actions__since' % include_group[0])
                if since:
                    extra_data['since'] = since
            if item == "donated_more":
                since = query_params.get('%s_donated_more__since' % include_group[0])
                if since:
                    extra_data['since'] = since
            if item == "donated_times":
                since = query_params.get('%s_donated_times__since' % include_group[0])
                if since:
                    extra_data['since'] = since

            make_query_fn = query_data.get('query_fn', make_default_user_query)
            users, __human_query = make_query_fn(
                users, query_data, possible_values, item, extra_data)
            _human_query.append(__human_query)

        if not _human_query or (
            users.query.sql_with_params() == base_user_query.query.sql_with_params()):
            continue

        all_user_queries.append(users)
        human_query.append("(%s)" % " and ".join(_human_query))

    human_query = "\n or ".join(human_query)
    users = None
    for i, query in enumerate(all_user_queries):
        if i == 0:
            users = query
        else:
            users = users | query
    if users is None:
        users = base_user_query

    ### If both of user_name and user_email are filled out,
    ### search for anyone who matches EITHER condition, rather than both.
    extra_where = []
    extra_params = []
    if query_params.get("user_name"):
        extra_where.append(
            "CONCAT(`core_user`.`first_name`, ' ', `core_user`.`last_name`) LIKE %s")
        extra_params.append("%" + "%".join(query_params['user_name'].split()) + "%")
        human_query += "\n and name is like \"%s\"" % query_params['user_name']
    if query_params.get("user_email"):
        extra_where.append("`core_user`.`email` LIKE %s")
        extra_params.append("%" + query_params.get("user_email") + "%")
        human_query += "\n and email is like \"%s\"" % query_params['user_email']
    if len(extra_where):
        if len(extra_where) == 2:
            extra_where = ["(%s OR %s)" % tuple(extra_where)]
        users = users.extra(
            where=extra_where,
            params=extra_params)

    users = users.extra(select={'phone': (
                "SELECT `normalized_phone` FROM `core_phone` "
                "WHERE `core_phone`.`user_id`=`core_user`.`id` "
                "LIMIT 1"),
                                'campus': (
                "SELECT `value` from `core_userfield` "
                "WHERE`core_userfield`.`parent_id`=`core_user`.`id` "
                'AND `core_userfield`.`name`="campus" LIMIT 1'),
                                'name': (
                "CONCAT(CONCAT(first_name, \" \"), last_name)"),
                                'skills': (
                "SELECT `value` from `core_userfield` "
                "WHERE`core_userfield`.`parent_id`=`core_user`.`id` "
                'AND `core_userfield`.`name`="skills" LIMIT 1'),
                                'engagement_level': (
                "SELECT `value` from `core_userfield` "
                "WHERE`core_userfield`.`parent_id`=`core_user`.`id` "
                'AND `core_userfield`.`name`="engagement_level" LIMIT 1'),
                                'affiliation': (
                "SELECT `value` from `core_userfield` "
                "WHERE`core_userfield`.`parent_id`=`core_user`.`id` "
                'AND `core_userfield`.`name`="affiliation" LIMIT 1'),
                                })
    if users.query.sql_with_params() == base_user_query.query.sql_with_params():
        users = base_user_query.none()

    if queryset_modifier_fn is not None:
        users = queryset_modifier_fn(users)

    if not query_params.get('subscription_all_users', False):
        users = users.filter(subscription_status='subscribed')
        human_query += "\n and subscription_status is 'subscribed'"

    users = users.distinct()
    raw_sql = sql.raw_sql_from_queryset(users)

    del users

    return Query(human_query, querystring, raw_sql, None)