Ejemplo n.º 1
0
    def calculate_funnel_correlation_persons(
        self, request: request.Request
    ) -> Dict[str, Tuple[list, Optional[str], Optional[str]]]:
        if request.user.is_anonymous or not self.team:
            return {"result": ([], None, None)}

        filter = Filter(request=request, data={"insight": INSIGHT_FUNNELS}, team=self.team)
        if not filter.correlation_person_limit:
            filter = filter.with_data({FUNNEL_CORRELATION_PERSON_LIMIT: 100})
        base_uri = request.build_absolute_uri("/")
        actors, serialized_actors = FunnelCorrelationActors(
            filter=filter, team=self.team, base_uri=base_uri
        ).get_actors()
        _should_paginate = should_paginate(actors, filter.correlation_person_limit)

        next_url = (
            format_query_params_absolute_url(
                request,
                filter.correlation_person_offset + filter.correlation_person_limit,
                offset_alias=FUNNEL_CORRELATION_PERSON_OFFSET,
                limit_alias=FUNNEL_CORRELATION_PERSON_LIMIT,
            )
            if _should_paginate
            else None
        )
        initial_url = format_query_params_absolute_url(request, 0)

        # cached_function expects a dict with the key result
        return {"result": (serialized_actors, next_url, initial_url)}
Ejemplo n.º 2
0
    def persons(self, request: Request, **kwargs) -> Response:
        cohort: Cohort = self.get_object()
        team = self.team
        filter = Filter(request=request, team=self.team)

        is_csv_request = self.request.accepted_renderer.format == "csv"
        if is_csv_request:
            filter = filter.with_data({LIMIT: CSV_EXPORT_LIMIT, OFFSET: 0})
        elif not filter.limit:
            filter = filter.with_data({LIMIT: 100})

        query, params = PersonQuery(filter, team.pk, cohort=cohort).get_query()

        raw_result = sync_execute(query, params)
        actor_ids = [row[0] for row in raw_result]
        actors, serialized_actors = get_people(team.pk, actor_ids)

        _should_paginate = should_paginate(actors, filter.limit)
        next_url = format_query_params_absolute_url(
            request, filter.offset +
            filter.limit) if _should_paginate else None
        previous_url = (format_query_params_absolute_url(
            request, filter.offset -
            filter.limit) if filter.offset - filter.limit >= 0 else None)

        return Response({
            "results": serialized_actors,
            "next": next_url,
            "previous": previous_url
        })
Ejemplo n.º 3
0
    def calculate_path_persons(
        self, request: Request
    ) -> Dict[str, Tuple[list, Optional[str], Optional[str]]]:
        if request.user.is_anonymous or not self.team:
            return {"result": ([], None, None)}

        filter = PathFilter(request=request,
                            data={"insight": INSIGHT_PATHS},
                            team=self.team)

        funnel_filter = None
        funnel_filter_data = request.GET.get(
            "funnel_filter") or request.data.get("funnel_filter")
        if funnel_filter_data:
            if isinstance(funnel_filter_data, str):
                funnel_filter_data = json.loads(funnel_filter_data)
            funnel_filter = Filter(data={
                "insight": INSIGHT_FUNNELS,
                **funnel_filter_data
            },
                                   team=self.team)

        people, should_paginate = ClickhousePathsPersons(
            filter, self.team, funnel_filter=funnel_filter).run()
        limit = filter.limit or 100
        next_url = format_query_params_absolute_url(
            request, filter.offset + limit) if should_paginate else None
        initial_url = format_query_params_absolute_url(request, 0)

        # cached_function expects a dict with the key result
        return {"result": (people, next_url, initial_url)}
Ejemplo n.º 4
0
    def persons(self, request: Request, **kwargs) -> Response:
        cohort: Cohort = self.get_object()
        team = self.team
        filter = Filter(request=request, team=self.team)

        if not filter.limit:
            filter = filter.with_data({LIMIT: 100})

        raw_result = sync_execute(
            GET_STATIC_COHORTPEOPLE_BY_COHORT_ID
            if cohort.is_static else GET_COHORTPEOPLE_BY_COHORT_ID,
            {
                "team_id": team.pk,
                "cohort_id": cohort.pk,
                "limit": filter.limit,
                "offset": filter.offset
            },
        )
        actor_ids = [row[0] for row in raw_result]
        actors, serialized_actors = get_people(team.pk, actor_ids)

        _should_paginate = should_paginate(actors, filter.limit)
        next_url = format_query_params_absolute_url(
            request, filter.offset +
            filter.limit) if _should_paginate else None
        previous_url = (format_query_params_absolute_url(
            request, filter.offset -
            filter.limit) if filter.offset - filter.limit >= 0 else None)

        return Response({
            "results": serialized_actors,
            "next": next_url,
            "previous": previous_url
        })
Ejemplo n.º 5
0
 def _return_activity_page(activity_page: ActivityPage, limit: int, page: int, request: request.Request) -> Response:
     return Response(
         {
             "results": ActivityLogSerializer(activity_page.results, many=True,).data,
             "next": format_query_params_absolute_url(request, page + 1, limit, offset_alias="page")
             if activity_page.has_next
             else None,
             "previous": format_query_params_absolute_url(request, page - 1, limit, offset_alias="page")
             if activity_page.has_previous
             else None,
             "total_count": activity_page.total_count,
         },
         status=status.HTTP_200_OK,
     )
Ejemplo n.º 6
0
    def run(self) -> Dict[str, Any]:
        from posthog.api.person import PersonSerializer

        distinct_id, start_time, snapshots = self.get_snapshot_data()

        # Apply limit and offset after decompressing to account for non-fully formed chunks.
        snapshots_subset = snapshots[self._offset:(self._offset + self._limit)]
        duration = 0
        if len(snapshots) > 1:
            duration = get_milliseconds_between_dates(
                datetime.fromtimestamp(snapshots[-1].get("timestamp", 0) /
                                       1000.0),
                datetime.fromtimestamp(snapshots[0].get("timestamp", 0) /
                                       1000.0),
            )
        has_next = len(snapshots) > (self._offset + self._limit + 1)
        next_url = (format_query_params_absolute_url(
            self._request, self._offset +
            self._limit, self._limit) if has_next else None)

        person = (PersonSerializer(
            Person.objects.get(team=self._team,
                               persondistinctid__distinct_id=distinct_id)).data
                  if distinct_id else None)

        return {
            "snapshots": snapshots_subset,
            "person": person,
            "start_time": start_time,
            "next": next_url,
            "duration": duration,
        }
Ejemplo n.º 7
0
    def calculate_funnel_persons(
        self, request: request.Request
    ) -> Dict[str, Tuple[list, Optional[str], Optional[str]]]:
        if request.user.is_anonymous or not self.team:
            return {"result": ([], None, None)}

        filter = Filter(request=request, data={"insight": INSIGHT_FUNNELS}, team=self.team)
        if not filter.limit:
            filter = filter.with_data({LIMIT: 100})

        funnel_actor_class = get_funnel_actor_class(filter)

        actors, serialized_actors = funnel_actor_class(filter, self.team).get_actors()
        _should_paginate = should_paginate(actors, filter.limit)
        next_url = format_query_params_absolute_url(request, filter.offset + filter.limit) if _should_paginate else None
        initial_url = format_query_params_absolute_url(request, 0)

        # cached_function expects a dict with the key result
        return {"result": (serialized_actors, next_url, initial_url)}
Ejemplo n.º 8
0
    def get_snapshots(self) -> RecordingSnapshots:
        all_recording_snapshots = [event.snapshot_data for event in list(self._query_recording_snapshots())]
        paginated_chunks = paginate_chunk_decompression(
            self._team.pk, self._session_recording_id, all_recording_snapshots, self._limit, self._offset
        )

        next_url = (
            format_query_params_absolute_url(self._request, self._offset + self._limit, self._limit)
            if paginated_chunks.has_next
            else None
        )

        return RecordingSnapshots(next=next_url, snapshots=paginated_chunks.paginated_list)
Ejemplo n.º 9
0
    def calculate_funnel_persons(
        self, request: Request
    ) -> Dict[str, Tuple[list, Optional[str], Optional[str]]]:
        if request.user.is_anonymous or not self.team:
            return {"result": ([], None, None)}

        filter = Filter(request=request,
                        data={"insight": INSIGHT_FUNNELS},
                        team=self.team)
        funnel_class: Callable = ClickhouseFunnelPersons

        if filter.funnel_viz_type == FunnelVizType.TRENDS:
            funnel_class = ClickhouseFunnelTrendsPersons

        people, should_paginate = funnel_class(filter, self.team).run()
        limit = filter.limit if filter.limit else 100
        next_url = format_query_params_absolute_url(
            request, filter.offset + limit) if should_paginate else None
        initial_url = format_query_params_absolute_url(request, 0)

        # cached_function expects a dict with the key result
        return {"result": (people, next_url, initial_url)}
Ejemplo n.º 10
0
    def calculate_funnel_correlation_persons(
        self, request: Request
    ) -> Dict[str, Tuple[list, Optional[str], Optional[str]]]:
        if request.user.is_anonymous or not self.team:
            return {"result": ([], None, None)}

        filter = Filter(request=request,
                        data={"insight": INSIGHT_FUNNELS},
                        team=self.team)
        people, should_paginate = FunnelCorrelationPersons(
            filter=filter, team=self.team).run()

        limit = filter.correlation_person_limit if filter.correlation_person_limit else 100
        next_url = (format_query_params_absolute_url(
            request,
            filter.correlation_person_offset + limit,
            offset_alias=FUNNEL_CORRELATION_PERSON_OFFSET,
            limit_alias=FUNNEL_CORRELATION_PERSON_LIMIT,
        ) if should_paginate else None)
        initial_url = format_query_params_absolute_url(request, 0)

        # cached_function expects a dict with the key result
        return {"result": (people, next_url, initial_url)}
Ejemplo n.º 11
0
    def test_format_query_params_absolute_url(self):
        build_req = HttpRequest()
        build_req.META = {"HTTP_HOST": "www.testserver"}

        test_to_expected: list = [
            (None, (50, None), "http://www.testserver?offset=50"),
            (None, (50, None), "http://www.testserver?offset=50"),
            (None, (None, 50), "http://www.testserver?limit=50"),
            (None, (50, 100), "http://www.testserver?offset=50&limit=100"),
            (None, (None, None), "http://www.testserver"),
            ("http://www.testserver?offset=20", (50, None),
             "http://www.testserver?offset=50"),
            ("http://www.testserver?limit=20", (None, 50),
             "http://www.testserver?limit=50"),
            ("http://www.testserver?offset=20&limit=20", (50, 50),
             "http://www.testserver?offset=50&limit=50"),
            # test with alias
            (None, (50, None, "off2", "lim2"), "http://www.testserver?off2=50"
             ),
            (None, (50, None, "off2", "lim2"),
             "http://www.testserver?off2=50"),
            (None, (None, 50, "off2", "lim2"),
             "http://www.testserver?lim2=50"),
            (None, (50, 100, "off2", "lim2"),
             "http://www.testserver?off2=50&lim2=100"),
            (None, (None, None, "off2", "lim2"), "http://www.testserver"),
            ("http://www.testserver?off2=20", (50, None, "off2", "lim2"),
             "http://www.testserver?off2=50"),
            ("http://www.testserver?lim2=20", (None, 50, "off2", "lim2"),
             "http://www.testserver?lim2=50"),
            (
                "http://www.testserver?off2=20&lim2=20",
                (50, 50, "off2", "lim2"),
                "http://www.testserver?off2=50&lim2=50",
            ),
        ]

        for start_url, params, expected in test_to_expected:
            self.assertEqual(
                expected,
                format_query_params_absolute_url(Request(build_req, start_url),
                                                 *params))
Ejemplo n.º 12
0
    def snapshots(self, request: request.Request, **kwargs):
        session_recording_id = kwargs["pk"]
        filter = Filter(request=request)
        limit = filter.limit if filter.limit else DEFAULT_RECORDING_CHUNK_LIMIT
        offset = filter.offset if filter.offset else 0

        session_recording_snapshot_data = self._get_session_recording_snapshots(
            request, session_recording_id, limit, offset)

        if session_recording_snapshot_data.snapshot_data_by_window_id == {}:
            raise exceptions.NotFound("Snapshots not found")
        next_url = (format_query_params_absolute_url(request, offset +
                                                     limit, limit)
                    if session_recording_snapshot_data.has_next else None)

        return response.Response({
            "result": {
                "next":
                next_url,
                "snapshot_data_by_window_id":
                session_recording_snapshot_data.snapshot_data_by_window_id,
            }
        })