def city_gis(request, format=None):
    """
    Available endpoints:
    `Connection`,
    `Event`,
    `Monitoring`,
    `Position`
    """

    return Response({
        'connections': request.build_absolute_uri('connections'),
        'events': request.build_absolute_uri('events'),
        'monitoring': request.build_absolute_uri('monitoring'),
        'positions': request.build_absolute_uri('positions'),
    })
Ejemplo n.º 2
0
    def create(self, request, *args, **kwargs):
        try:
            validate_password(request.data.get('password'))
        except ValidationError as e:
            print('User creation failed: password did not validate.', e)
            return Response({'message': '\n'.join(e.messages)}, 400)

        try:
            User.objects.get(username=request.data.get('username'))
            return Response({'message': 'User already exists'}, 400)
        except ObjectDoesNotExist:
            pass

        response = super().create(request, *args, **kwargs)

        # Prep to send email.
        user = User.objects.get(username=response.data['username'])
        url = reverse('user-register', kwargs={'pk': user.id})
        registration_url = request.build_absolute_uri(url)

        try:
            send_registration_email_to_user.delay(registration_url,
                                                  user.registration_code,
                                                  user.email)
        except Exception as e:
            print('Error sending mail', e)
        return Response({'description': 'User created. Registration Needed'},
                        201)
Ejemplo n.º 3
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.º 4
0
    def create(self, request, *args, **kwargs):
        try:
            validate_password(request.data.get('password'))
        except ValidationError as e:
            logger.error('User creation failed: password did not validate.')
            return Response({ 'message': '\n'.join(e.messages) }, 400)

        try:
            User.objects.get(username=request.data.get('username'))
            logger.error('User creation failed: user already exists.')
            return Response({ 'message': 'User already exists' }, 400)
        except ObjectDoesNotExist:
            pass

        response = super().create(request, *args, **kwargs)

        # Prep to send email.
        user = User.objects.get(username=response.data['username'])
        url = reverse('api:user-register', kwargs={'pk': user.id})
        registration_url = request.build_absolute_uri(url)

        try:
            send_registration_email_to_user.delay(registration_url,
                user.registration_code, user.email)
        except Exception as e:
            logger.error('An exception occurred while creating user. %s' % e)
        return Response({
            'description': 'User created. Registration Needed'
        }, 201)
Ejemplo n.º 5
0
    def list(self, request: request.Request, *args: Any,
             **kwargs: Any) -> response.Response:
        queryset = self.get_queryset()
        monday = now() + timedelta(days=-now().weekday())
        events = queryset.filter(
            timestamp__gte=monday.replace(hour=0, minute=0, second=0))[0:101]

        if len(events) < 101:
            events = queryset[0:101]

        prefetched_events = self._prefetch_events([event for event in events])
        path = request.get_full_path()

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

        return response.Response({
            "next":
            next_url,
            "results":
            EventSerializer(prefetched_events, many=True).data,
        })
Ejemplo n.º 6
0
    def list(self, request: request.Request, *args: Any,
             **kwargs: Any) -> response.Response:
        queryset = self.get_queryset()
        monday = now() + timedelta(days=-now().weekday())
        events = queryset.filter(
            timestamp__gte=monday.replace(hour=0, minute=0, second=0))[0:101]

        if len(events) < 101:
            events = queryset[0:101]

        prefetched_events = self._prefetch_events([event for event in events])
        path = request.get_full_path()

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

        return response.Response({
            'next':
            next_url,
            'results':
            EventSerializer(prefetched_events, many=True).data
        })
def city_gis(request, format=None):
    """
    Available endpoints:
    `Connection`,
    `Event`,
    `Monitoring`,
    `Position`
    """

    return Response(
        {
            'connections': request.build_absolute_uri('connections'),
            'events': request.build_absolute_uri('events'),
            'monitoring': request.build_absolute_uri('monitoring'),
            'positions': request.build_absolute_uri('positions'),
        }
    )
Ejemplo n.º 8
0
 def calculate_retention(self, request: request.Request) -> Dict[str, Any]:
     team = self.team
     data = {}
     if not request.GET.get("date_from"):
         data.update({"date_from": "-11d"})
     filter = RetentionFilter(data=data, request=request, team=self.team)
     base_uri = request.build_absolute_uri("/")
     result = ClickhouseRetention(base_uri=base_uri).run(filter, team)
     return {"result": result}
Ejemplo n.º 9
0
 def _build_next_url(self, request: request.Request, last_event_timestamp: datetime) -> str:
     params = request.GET.dict()
     reverse = request.GET.get("orderBy", "-timestamp") != "-timestamp"
     timestamp = last_event_timestamp.astimezone().isoformat()
     if reverse:
         params["after"] = timestamp
     else:
         params["before"] = timestamp
     return request.build_absolute_uri(f"{request.path}?{urllib.parse.urlencode(params)}")
Ejemplo n.º 10
0
def add_submission_with(request, username, id_string):

    import uuid
    import requests

    from django.template import loader, Context
    from dpath import util as dpath_util
    from dict2xml import dict2xml

    def geopoint_xpaths(username, id_string):
        d = DataDictionary.objects.get(user__username__iexact=username,
                                       id_string__exact=id_string)
        return [
            e.get_abbreviated_xpath() for e in d.get_survey_elements()
            if e.bind.get(u'type') == u'geopoint'
        ]

    value = request.GET.get('coordinates')
    xpaths = geopoint_xpaths(username, id_string)
    xml_dict = {}
    for path in xpaths:
        dpath_util.new(xml_dict, path, value)

    context = {
        'username': username,
        'id_string': id_string,
        'xml_content': dict2xml(xml_dict)
    }
    instance_xml = loader.get_template("instance_add.xml")\
        .render(Context(context))

    url = settings.ENKETO_API_INSTANCE_IFRAME_URL
    return_url = reverse('thank_you_submission',
                         kwargs={
                             "username": username,
                             "id_string": id_string
                         })
    if settings.DEBUG:
        openrosa_url = "https://dev.formhub.org/{}".format(username)
    else:
        openrosa_url = request.build_absolute_uri("/{}".format(username))
    payload = {
        'return_url': return_url,
        'form_id': id_string,
        'server_url': openrosa_url,
        'instance': instance_xml,
        'instance_id': uuid.uuid4().hex
    }

    r = requests.post(url,
                      data=payload,
                      auth=(settings.ENKETO_API_TOKEN, ''),
                      verify=False)

    return HttpResponse(r.text, content_type='application/json')
Ejemplo n.º 11
0
 def authenticate(self, request: request.Request):
     # if the Origin is different, the only authentication method should be temporary_token
     # This happens when someone is trying to create actions from the editor on their own website
     if request.headers.get('Origin') and request.headers['Origin'] not in request.build_absolute_uri('/'):
         if not request.GET.get('temporary_token'):
             raise AuthenticationFailed(detail='No token')
     if request.GET.get('temporary_token'):
         user = User.objects.filter(temporary_token=request.GET.get('temporary_token'))
         if not user.exists():
             raise AuthenticationFailed(detail='User doesnt exist')
         return (user.first(), None)
     return None
Ejemplo n.º 12
0
def format_next_url(request: request.Request, offset: int, page_size: int):
    next_url = request.get_full_path()
    if not next_url:
        return None

    if "offset" in next_url:
        next_url = next_url[1:]
        next_url = next_url.replace("offset=" + str(offset),
                                    "offset=" + str(offset + page_size))
    else:
        next_url = request.build_absolute_uri("{}{}offset={}".format(
            next_url, "&" if "?" in next_url else "?", offset + page_size))
    return next_url
Ejemplo n.º 13
0
    def people(self, request: request.Request, *args: Any,
               **kwargs: Any) -> Response:
        team = self.team
        filter = Filter(request=request, team=self.team)
        entity = get_target_entity(filter)

        actors, serialized_actors = ClickhouseTrendsActors(
            team, entity, filter).get_actors()

        current_url = request.get_full_path()
        next_url: Optional[str] = request.get_full_path()
        offset = filter.offset
        if len(actors) > 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

        if request.accepted_renderer.format == "csv":
            csvrenderers.CSVRenderer.header = [
                "Distinct ID", "Internal ID", "Email", "Name", "Properties"
            ]
            content = [{
                "Name":
                get_person_name(person),
                "Distinct ID":
                person.distinct_ids[0] if person.distinct_ids else "",
                "Internal ID":
                str(person.uuid),
                "Email":
                person.properties.get("email"),
                "Properties":
                person.properties,
            } for person in actors if isinstance(person, Person)]
            return Response(content)

        return Response({
            "results": [{
                "people": serialized_actors[0:100],
                "count": len(serialized_actors[0:100])
            }],
            "next":
            next_url,
            "previous":
            current_url[1:],
        })
Ejemplo n.º 14
0
def paginated_result(entites: Union[List[Dict[str, Any]], ReturnDict],
                     request: request.Request,
                     offset: int = 0) -> Optional[str]:
    next_url: Optional[str] = request.get_full_path()
    if len(entites) > 99 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 next_url
Ejemplo n.º 15
0
 def authenticate(self, request: request.Request):
     # if the Origin is different, the only authentication method should be temporary_token
     # This happens when someone is trying to create actions from the editor on their own website
     if request.headers.get('Origin') and request.headers['Origin'] not in request.build_absolute_uri('/'):
         if not request.GET.get('temporary_token'):
             raise AuthenticationFailed(detail="""No temporary_token set.
                 That means you're either trying to access this API from a different site,
                 or it means your proxy isn\'t sending the correct headers.
                 See https://github.com/PostHog/posthog/wiki/Running-behind-a-proxy for more information.
                 """)
     if request.GET.get('temporary_token'):
         user = User.objects.filter(temporary_token=request.GET.get('temporary_token'))
         if not user.exists():
             raise AuthenticationFailed(detail='User doesnt exist')
         return (user.first(), None)
     return None
Ejemplo n.º 16
0
def add_submission_with(request, username, id_string):

    import uuid
    import requests

    from django.template import loader, Context
    from dpath import util as dpath_util
    from dict2xml import dict2xml

    def geopoint_xpaths(username, id_string):
        d = DataDictionary.objects.get(
            user__username__iexact=username, id_string__exact=id_string)
        return [e.get_abbreviated_xpath()
                for e in d.get_survey_elements()
                if e.bind.get(u'type') == u'geopoint']

    value = request.GET.get('coordinates')
    xpaths = geopoint_xpaths(username, id_string)
    xml_dict = {}
    for path in xpaths:
        dpath_util.new(xml_dict, path, value)

    context = {'username': username,
               'id_string': id_string,
               'xml_content': dict2xml(xml_dict)}
    instance_xml = loader.get_template("instance_add.xml")\
        .render(Context(context))

    url = settings.ENKETO_API_INSTANCE_IFRAME_URL
    return_url = reverse('thank_you_submission',
                         kwargs={"username": username, "id_string": id_string})
    if settings.DEBUG:
        openrosa_url = "https://dev.formhub.org/{}".format(username)
    else:
        openrosa_url = request.build_absolute_uri("/{}".format(username))
    payload = {'return_url': return_url,
               'form_id': id_string,
               'server_url': openrosa_url,
               'instance': instance_xml,
               'instance_id': uuid.uuid4().hex}

    r = requests.post(url, data=payload,
                      auth=(settings.ENKETO_API_TOKEN, ''), verify=False)

    return HttpResponse(r.text, content_type='application/json')
Ejemplo n.º 17
0
    def retention(self, request: request.Request) -> response.Response:

        display = request.GET.get("display", None)
        team = cast(User, request.user).team
        if not team:
            return response.Response(
                {"message": "Could not retrieve team", "detail": "Could not validate team associated with user"},
                status=400,
            )
        filter = RetentionFilter(request=request, team=team)
        base_uri = request.build_absolute_uri("/")

        if display == TRENDS_TABLE:
            people = self.retention_class(base_uri=base_uri).actors_in_period(filter, team)
        else:
            people = self.retention_class(base_uri=base_uri).actors(filter, team)

        next_url = paginated_result(people, request, filter.offset)

        return response.Response({"result": people, "next": next_url})
Ejemplo n.º 18
0
def format_paginated_url(request: request.Request,
                         offset: int,
                         page_size: int,
                         mode=PaginationMode.next):
    result = request.get_full_path()
    if not result:
        return None

    new_offset = offset - page_size if mode == PaginationMode.previous else offset + page_size

    if new_offset < 0:
        return None

    if "offset" in result:
        result = result[1:]
        result = result.replace(f"offset={offset}", f"offset={new_offset}")
    else:
        result = request.build_absolute_uri("{}{}offset={}".format(
            result, "&" if "?" in result else "?", new_offset))
    return result
Ejemplo n.º 19
0
 def authenticate(self, request: request.Request):
     # if the Origin is different, the only authentication method should be temporary_token
     # This happens when someone is trying to create actions from the editor on their own website
     if (
         request.headers.get("Origin")
         and urlsplit(request.headers["Origin"]).netloc not in urlsplit(request.build_absolute_uri("/")).netloc
     ):
         if not request.GET.get("temporary_token"):
             raise AuthenticationFailed(
                 detail="No temporary_token set. "
                 + "That means you're either trying to access this API from a different site, "
                 + "or it means your proxy isn't sending the correct headers. "
                 + "See https://posthog.com/docs/deployment/running-behind-proxy for more information."
             )
     if request.GET.get("temporary_token"):
         user_model = apps.get_model(app_label="posthog", model_name="User")
         user = user_model.objects.filter(temporary_token=request.GET.get("temporary_token"))
         if not user.exists():
             raise AuthenticationFailed(detail="User doesnt exist")
         return (user.first(), None)
     return None
Ejemplo n.º 20
0
    def list(self, request: request.Request, *args: Any,
             **kwargs: Any) -> response.Response:
        is_csv_request = self.request.accepted_renderer.format == "csv"
        monday = now() + timedelta(days=-now().weekday())
        # Don't allow events too far into the future
        queryset = self.get_queryset().filter(timestamp__lte=now() +
                                              timedelta(seconds=5))
        next_url: Optional[str] = None

        if is_csv_request:
            events = queryset[:self.CSV_EXPORT_LIMIT]
        else:
            events = queryset.filter(timestamp__gte=monday.replace(
                hour=0, minute=0, second=0))[:101]
            if len(events) < 101:
                events = queryset[:101]
            path = request.get_full_path()
            reverse = request.GET.get("orderBy", "-timestamp") != "-timestamp"
            if len(events) > 100:
                next_url = request.build_absolute_uri("{}{}{}={}".format(
                    path,
                    "&" if "?" in path else "?",
                    "after" if reverse else "before",
                    events[99].timestamp.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
                ))
            events = self.paginator.paginate_queryset(
                events, request, view=self)  # type: ignore

        prefetched_events = self._prefetch_events(list(events))

        return response.Response({
            "next":
            next_url,
            "results":
            EventSerializer(prefetched_events,
                            many=True,
                            context={
                                "format": self.request.accepted_renderer.format
                            }).data,
        })
Ejemplo n.º 21
0
 def get(self, request):
     print(request.build_absolute_uri().split('/?redirect=')[1])
     target_url = request.build_absolute_uri().split('/?redirect=')[1]
     return redirect(target_url)
Ejemplo n.º 22
0
    def people(self, request: request.Request, *args: Any, **kwargs: Any) -> Response:
        team = request.user.team_set.get()
        filter = Filter(request=request)
        offset = int(request.GET.get("offset", 0))

        def _calculate_people(events: QuerySet, offset: int):
            shown_as = request.GET.get("shown_as")
            if shown_as is not None and shown_as == "Stickiness":
                stickiness_days = int(request.GET["stickiness_days"])
                events = (
                    events.values("person_id")
                    .annotate(
                        day_count=Count(functions.TruncDay("timestamp"), distinct=True)
                    )
                    .filter(day_count=stickiness_days)
                )
            else:
                events = events.values("person_id").distinct()

            if (
                request.GET.get("breakdown_type") == "cohort"
                and request.GET.get("breakdown_value") != "all"
            ):
                events = events.filter(
                    Exists(
                        CohortPeople.objects.filter(
                            cohort_id=int(request.GET["breakdown_value"]),
                            person_id=OuterRef("person_id"),
                        ).only("id")
                    )
                )

            people = Person.objects.filter(
                team=team,
                id__in=[p["person_id"] for p in events[offset : offset + 100]],
            )

            people = people.prefetch_related(
                Prefetch("persondistinctid_set", to_attr="distinct_ids_cache")
            )

            return serialize_people(people=people, request=request)

        filtered_events: QuerySet = QuerySet()
        if request.GET.get("session"):
            filtered_events = (
                Event.objects.filter(team=team)
                .filter(filter_events(team.pk, filter))
                .add_person_id(team.pk)
            )
        else:
            if len(filter.entities) >= 1:
                entity = filter.entities[0]
            else:
                entity = Entity(
                    {"id": request.GET["entityId"], "type": request.GET["type"]}
                )

            if entity.type == TREND_FILTER_TYPE_EVENTS:
                filtered_events = process_entity_for_events(
                    entity, team_id=team.pk, order_by=None
                ).filter(filter_events(team.pk, filter, entity))
            elif entity.type == TREND_FILTER_TYPE_ACTIONS:
                actions = super().get_queryset()
                actions = actions.filter(deleted=False)
                try:
                    action = actions.get(pk=entity.id)
                except Action.DoesNotExist:
                    return Response([])
                filtered_events = process_entity_for_events(
                    entity, team_id=team.pk, order_by=None
                ).filter(filter_events(team.pk, filter, entity))

        people = _calculate_people(events=filtered_events, offset=offset)

        current_url = request.get_full_path()
        next_url: Optional[str] = request.get_full_path()
        if people["count"] > 99 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], "next": next_url, "previous": current_url[1:]}
        )