Beispiel #1
0
    def session(self, request: Request, *args: Any, **kwargs: Any) -> Response:
        if not endpoint_enabled(CH_SESSION_ENDPOINT, request.user.distinct_id):
            result = super().calculate_session(request)
            return Response(result)

        team = request.user.team
        filter = Filter(request=request)

        limit = int(request.GET.get("limit", SESSIONS_LIST_DEFAULT_LIMIT))
        offset = int(request.GET.get("offset", 0))

        response = ClickhouseSessions().run(team=team,
                                            filter=filter,
                                            limit=limit + 1,
                                            offset=offset)

        if "distinct_id" in request.GET and request.GET["distinct_id"]:
            try:
                person_ids = get_persons_by_distinct_ids(
                    team.pk, [request.GET["distinct_id"]])[0].distinct_ids
                response = [
                    session for i, session in enumerate(response)
                    if response[i]["distinct_id"] in person_ids
                ]
            except IndexError:
                response = []

        if len(response) > limit:
            response.pop()
            return Response({"result": response, "offset": offset + limit})
        else:
            return Response({
                "result": response,
            })
Beispiel #2
0
    def retrieve(self,
                 request: Request,
                 pk: Optional[int] = None,
                 *args: Any,
                 **kwargs: Any) -> Response:

        if not endpoint_enabled(CH_EVENT_ENDPOINT, request.user.distinct_id):
            return super().retrieve(request, pk)

        # TODO: implement getting elements
        team = request.user.team_set.get()
        query_result = sync_execute(
            SELECT_ONE_EVENT_SQL,
            {
                "team_id": team.pk,
                "event_id": pk
            },
        )
        result = ClickhouseEventSerializer(query_result[0], many=False).data

        if result["elements_hash"]:
            result["elements"] = get_elements_by_elements_hash(
                result["elements_hash"], team.pk)

        return Response(result)
Beispiel #3
0
    def people(self, request: Request, *args: Any, **kwargs: Any) -> Response:

        if not endpoint_enabled(CH_ACTION_ENDPOINT, request.user.distinct_id):
            result = super().get_people(request)
            return Response(result)

        team = request.user.team
        filter = Filter(request=request)
        shown_as = request.GET.get("shown_as")

        if len(filter.entities) >= 1:
            entity = filter.entities[0]
        else:
            entity = Entity({
                "id": request.GET["entityId"],
                "type": request.GET["type"]
            })

        # adhoc date handling. parsed differently with django orm
        if filter.interval == "month":
            filter._date_to = (timezone.now() if not filter.date_from else (
                filter.date_from +
                timedelta(days=31)).strftime("%Y-%m-%d %H:%M:%S"))

        current_url = request.get_full_path()

        if shown_as is not None and shown_as == "Stickiness":
            stickiness_day = int(request.GET["stickiness_days"])
            serialized_people = self._calculate_stickiness_entity_people(
                team, entity, filter, stickiness_day)

        else:
            serialized_people = self._calculate_entity_people(
                team, entity, filter)

        current_url = request.get_full_path()
        next_url: Optional[str] = request.get_full_path()
        offset = filter.offset
        if len(serialized_people) > 100 and next_url:
            if "offset" in next_url:
                next_url = next_url[1:]
                next_url = next_url.replace("offset=" + str(offset),
                                            "offset=" + str(offset + 100))
            else:
                next_url = request.build_absolute_uri("{}{}offset={}".format(
                    next_url, "&" if "?" in next_url else "?", offset + 100))
        else:
            next_url = None

        return Response({
            "results": [{
                "people": serialized_people[0:100],
                "count": len(serialized_people[0:99])
            }],
            "next":
            next_url,
            "previous":
            current_url[1:],
        })
Beispiel #4
0
    def retrieve(self, request, pk=None):

        if not endpoint_enabled(CH_PERSON_ENDPOINT, request.user.distinct_id):
            return super().retrieve(request, pk)

        qres = sync_execute(PEOPLE_SQL.format(content_sql=[pk]), {"offset": 0})
        res = ClickhousePersonSerializer(qres[0]).data if len(qres) > 0 else []
        return Response(res)
Beispiel #5
0
    def list(self, request):

        if not endpoint_enabled(CH_PERSON_ENDPOINT, request.user.distinct_id):
            return super().list(request)

        team = self.request.user.team_set.get()
        filtered = self._ch_filter_request(self.request, team)
        results = ClickhousePersonSerializer(filtered, many=True).data
        return Response({"results": results})
Beispiel #6
0
    def list(self, request):

        if not endpoint_enabled(CH_PATH_ENDPOINT, request.user.distinct_id):
            result = super().get_list(request)
            return Response(result)

        team = request.user.team
        filter = Filter(request=request)
        resp = ClickhousePaths().run(filter=filter, team=team)
        return Response(resp)
Beispiel #7
0
    def funnel(self, request: Request, *args: Any, **kwargs: Any) -> Response:

        if not endpoint_enabled(CH_FUNNEL_ENDPOINT, request.user.distinct_id):
            result = super().calculate_funnel(request)
            return Response(result)

        team = request.user.team
        filter = Filter(request=request)
        response = ClickhouseFunnel(team=team, filter=filter).run()
        return Response(response)
Beispiel #8
0
    def path(self, request: Request, *args: Any, **kwargs: Any) -> Response:

        if not endpoint_enabled(CH_PATH_ENDPOINT, request.user.distinct_id):
            result = super().calculate_path(request)
            return Response(result)

        team = request.user.team
        filter = Filter(request=request)
        resp = ClickhousePaths().run(filter=filter, team=team)
        return Response(resp)
Beispiel #9
0
    def values(self, request: Request) -> Response:

        if not endpoint_enabled(CH_EVENT_ENDPOINT, request.user.distinct_id):
            return Response(super().get_values(request))

        key = request.GET.get("key")
        team = request.user.team
        result = []
        if key:
            result = get_property_values_for_key(key, team, value=request.GET.get("value"))
        return Response([{"name": convert_property_value(value[0])} for value in result])
Beispiel #10
0
    def retention(self, request: Request, *args: Any,
                  **kwargs: Any) -> Response:

        if not endpoint_enabled(CH_RETENTION_ENDPOINT,
                                request.user.distinct_id):
            result = super().calculate_retention(request)
            return Response({"data": result})

        team = request.user.team
        filter = Filter(request=request)
        result = ClickhouseRetention().run(filter, team)
        return Response({"data": result})
Beispiel #11
0
    def by_distinct_id(self, request):

        if not endpoint_enabled(CH_PERSON_ENDPOINT, request.user.distinct_id):
            result = super().get_by_distinct_id(request)
            return Response(result)

        distinct_id = str(request.GET["distinct_id"])
        result = sync_execute(
            PEOPLE_THROUGH_DISTINCT_SQL.format(content_sql=[distinct_id]),
            {"offset": 0})
        res = ClickhousePersonSerializer(
            result[0]).data if len(result) > 0 else []
        return Response(res)
Beispiel #12
0
    def elements(self, request: request.Request):

        if not endpoint_enabled(CH_PATH_ENDPOINT, request.user.distinct_id):
            result = super().get_elements(request)
            return Response(result)

        team = request.user.team_set.get()
        response = sync_execute(ELEMENT_TAG_COUNT, {"team_id": team.pk, "limit": 20})

        resp = []
        for row in response:
            resp.append({"name": row[0], "id": row[1], "count": row[2]})

        return Response(resp)
Beispiel #13
0
    def list(self, request: Request, *args: Any, **kwargs: Any) -> Response:

        if not endpoint_enabled(CH_EVENT_ENDPOINT, request.user.distinct_id):
            return super().list(request)

        team = request.user.team
        filter = Filter(request=request)
        if request.GET.get("after"):
            filter._date_from = request.GET["after"]
        if request.GET.get("before"):
            filter._date_to = request.GET["before"]
        limit = "LIMIT 101"
        conditions, condition_params = determine_event_conditions(request.GET.dict())
        prop_filters, prop_filter_params = parse_prop_clauses("uuid", filter.properties, team)

        if prop_filters != "":
            query_result = sync_execute(
                SELECT_EVENT_WITH_PROP_SQL.format(conditions=conditions, limit=limit, filters=prop_filters),
                {"team_id": team.pk, **condition_params, **prop_filter_params},
            )
        else:
            query_result = sync_execute(
                SELECT_EVENT_WITH_ARRAY_PROPS_SQL.format(conditions=conditions, limit=limit),
                {"team_id": team.pk, **condition_params},
            )

        result = ClickhouseEventSerializer(
            query_result,
            many=True,
            context={
                "elements": self._get_elements(query_result, team),
                "people": self._get_people(query_result, team),
            },
        ).data

        if len(query_result) > 100:
            path = request.get_full_path()
            reverse = request.GET.get("orderBy", "-timestamp") != "-timestamp"
            next_url: Optional[str] = request.build_absolute_uri(
                "{}{}{}={}".format(
                    path,
                    "&" if "?" in path else "?",
                    "after" if reverse else "before",
                    query_result[99][3].strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
                )
            )
        else:
            next_url = None

        return Response({"next": next_url, "results": result})
Beispiel #14
0
    def trend(self, request: Request, *args: Any, **kwargs: Any) -> Response:
        if not endpoint_enabled(CH_TREND_ENDPOINT, request.user.distinct_id):
            result = super().calculate_trends(request)
            return Response(result)

        team = request.user.team
        filter = Filter(request=request)

        if filter.shown_as == TRENDS_STICKINESS:
            result = ClickhouseStickiness().run(filter, team)
        else:
            result = ClickhouseTrends().run(filter, team)

        self._refresh_dashboard(request=request)

        return Response(result)
Beispiel #15
0
    def properties(self, request: Request) -> Response:

        if not endpoint_enabled(CH_PERSON_ENDPOINT, request.user.distinct_id):
            result = super().get_properties(request)
            return Response(result)

        team = self.request.user.team_set.get()
        qres = sync_execute(GET_PERSON_TOP_PROPERTIES, {
            "limit": 10,
            "team_id": team.pk
        })

        return Response([{
            "name": element[0],
            "count": element[1]
        } for element in qres])
Beispiel #16
0
    def session(self, request: Request, *args: Any, **kwargs: Any) -> Response:
        if not endpoint_enabled(CH_SESSION_ENDPOINT, request.user.distinct_id):
            result = super().calculate_session(request)
            return Response(result)

        team = request.user.team
        filter = Filter(request=request)

        limit = int(request.GET.get("limit", SESSIONS_LIST_DEFAULT_LIMIT))
        offset = int(request.GET.get("offset", 0))

        response = ClickhouseSessions().run(team=team,
                                            filter=filter,
                                            limit=limit + 1,
                                            offset=offset)

        if len(response) > limit:
            response.pop()
            return Response({"result": response, "offset": offset + limit})
        else:
            return Response({
                "result": response,
            })