Example #1
0
    def call(self, request, *args, **kwargs):
        """
        Get the mobile of this Shout
        ##Response
        <pre><code>
        {
            "mobile": "01701700555"
        }
        </code></pre>

        This endpoint will be throttled to prevent multiple requests from same client in short time.
        ---
        omit_serializer: true
        omit_parameters:
            - form
        """
        user = request.user
        profile = user.ap
        shout = self.get_object()
        mobile = shout.mobile if shout.is_mobile_set else None
        if not mobile:
            raise ShoutitBadRequest(_("No mobile to be called"))
        track_properties = {
            'api_client': getattr(request, 'api_client', None),
            'api_version': request.version,
            'mp_country_code': profile.country,
            '$region': profile.state,
            '$city': profile.city,
            'shout_id': shout.pk,
            'shout_country': shout.get_country_display(),
            'shout_region': shout.state,
            'shout_city': shout.city,
        }
        mixpanel_controller.track(user.pk, 'show_mobile', track_properties)
        return Response({'mobile': mobile})
Example #2
0
    def video_call(self, request):
        """
        Send the Profile Push about video call
        ###REQUIRES AUTH
        ###Request
        <pre><code>
        {
          "identity": "7c6ca4737db3447f936037374473e61f",
          "missed": true
        }
        </code></pre>

        ---
        """
        # Todo: Move the logic to Serializer
        data = request.data
        identity = data.get('identity')
        if not identity:
            raise RequiredBody('identity')
        try:
            video_client = VideoClient.objects.get(id=identity)
        except VideoClient.DoesNotExist:
            msg = _("Profile with identity %(identity)s does not exist") % {
                'identity': identity
            }
            raise InvalidParameter('identity', message=msg)
        except ValueError:
            msg = _("Invalid identity")
            raise InvalidParameter('identity', message=msg)
        other_user = video_client.user

        missed = data.get('missed', False)

        if missed:
            # Notify the other user about the missed video call
            notifications_controller.notify_user_of_missed_video_call(
                user=other_user, caller=request.user)
        else:
            # Notify the other user about the incoming video call
            notifications_controller.notify_user_of_incoming_video_call(
                user=other_user, caller=request.user)

        # Track
        event_name = NOTIFICATION_TYPE_MISSED_VIDEO_CALL if missed else NOTIFICATION_TYPE_INCOMING_VIDEO_CALL
        caller = request.user
        track_properties = {
            'mp_country_code': caller.ap.country,
            '$region': caller.ap.state,
            '$city': caller.ap.city,
            'api_client': getattr(request, 'api_client', None),
            'called_profile': other_user.pk
        }
        mixpanel_controller.track(caller.pk, str(event_name), track_properties)

        return Response()
Example #3
0
    def post_access_token_request(self):
        request = self.request
        data = request.data
        user = request.user
        new_signup = getattr(user, 'new_signup', False)

        mixpanel_distinct_id = data.get('mixpanel_distinct_id')
        invitation_code = data.get('invitation_code')
        track_properties = {
            'profile': user.pk,
            'api_client': data.get('client_id'),
            'api_version': request.version,
            'using': data.get('grant_type'),
            'server': request.META.get('HTTP_HOST'),
            'mp_country_code': user.location.get('country'),
            '$region': user.location.get('state'),
            '$city': user.location.get('city'),
            'has_push_tokens': user.devices.count() > 0,
            'invitation_code': invitation_code
        }

        if new_signup:
            event_name = "signup_guest" if user.is_guest else 'signup'
            # Apply InviteFriends
            if invitation_code:
                apply_invite_friends(request.user, invitation_code)
        else:
            event_name = 'login'

        if mixpanel_distinct_id:
            # Alias the Mixpanel id and track
            mixpanel_controller.alias(user.pk,
                                      mixpanel_distinct_id,
                                      event_name,
                                      track_properties,
                                      add=True)
        else:
            # Track only
            mixpanel_controller.track(user.pk,
                                      event_name,
                                      track_properties,
                                      add=True)
            # Y U NO send us Mixpanel?
            if data.get('grant_type') != 'refresh_token':
                extra = {
                    'request': request._request,
                    'agent': request.agent,
                    'build_no': request.build_no,
                    'track_properties': track_properties,
                    'request_data': data
                }
                error_logger.warning(
                    'AccessToken request without mixpanel_distinct_id',
                    extra=extra)
Example #4
0
def shout_post_save(sender, instance=None, created=False, **kwargs):
    # Create / Update ShoutIndex
    if getattr(instance, 'save_shout_index', True):
        save_shout_index(instance, created)

    if created:
        # Track
        if not instance.is_sss:
            mixpanel_controller.track(instance.user.pk, 'new_shout',
                                      instance.track_properties)

    # Pre cache on Facebook Graph
    # https://developers.facebook.com/docs/sharing/best-practices/#precaching
    if instance.item.thumbnail:
        facebook_controller.pre_cache_graph(instance.web_url)

    # Publish to Facebook
    if getattr(instance, 'publish_to_facebook',
               False) and 'facebook' not in instance.published_on:
        publish_shout_to_facebook.delay(instance)
Example #5
0
def publish_shout_to_facebook(shout):
    la = getattr(shout.user, 'linked_facebook', None)
    if not la:
        debug_logger.debug(
            'No linked_facebook, skip publishing Shout %s on Facebook' % shout)
        return
    if 'publish_actions' not in la.scopes:
        debug_logger.debug(
            'No publish_actions in scopes, skip publishing Shout %s on Facebook'
            % shout)
        return
    prod = settings.SHOUTIT_ENV == 'prod'
    namespace = 'shoutitcom' if prod else 'shoutitcom-' + settings.SHOUTIT_ENV
    actions_url = 'https://graph.facebook.com/v2.6/me/%s:shout' % namespace
    params = {
        'access_token': la.access_token,
        shout.get_type_display(): shout.web_url,
        'privacy': "{'value':'EVERYONE'}"
    }
    if prod:
        params['fb:explicitly_shared'] = True
    res = requests.post(actions_url, params=params).json()
    id_on_facebook = res.get('id')
    if id_on_facebook:
        shout.published_on['facebook'] = id_on_facebook
        shout.save(update_fields=['published_on'])
        # Track
        mixpanel_controller.track(shout.user.pk, 'share_shout_on_fb',
                                  shout.track_properties)
        debug_logger.debug('Published shout %s on Facebook' % shout)
    else:
        error_logger.warn('Error publishing shout on Facebook',
                          extra={
                              'res': res,
                              'shout': shout
                          })
Example #6
0
    def list(self, request, *args, **kwargs):
        """
        List shouts.
        [Shouts Pagination](https://github.com/shoutit/shoutit-api/wiki/Searching-Shouts#pagination)
        ###Response
        <pre><code>
        {
            "count": 59, // number of results
            "next": null, // next results page url
            "previous": null, // previous results page url
            "results": [] // list of {ShoutSerializer}
            "related_searches": [] // list of keywords related to the current search [currently dummy text is being returned]
        }
        </code></pre>
        ---
        serializer: ShoutSerializer
        parameters:
            - name: search
              description: space or comma separated keywords to search in title, text, tags
              paramType: query
            - name: shout_type
              paramType: query
              defaultValue: all
              enum:
                - request
                - offer
                - all
            - name: country
              paramType: query
            - name: city
              paramType: query
            - name: state
              paramType: query
            - name: category
              description: the category slug
              paramType: query
            - name: tags
              description: space or comma separated tags. returned shouts will contain ALL of them. passing single tag is also possible to list its shouts
              paramType: query
            - name: discover
              description: discover item id to list its shouts
              paramType: query
            - name: profile
              description: profile username to list its shouts
              paramType: query
            - name: min_price
              paramType: query
            - name: max_price
              paramType: query
            - name: down_left_lat
              description: -90 to 90, can not be greater than up_right_lat
              paramType: query
            - name: down_left_lng
              description: -180 to 180, can not be greater than up_right_lng
              paramType: query
            - name: up_right_lat
              description: -90 to 90
              paramType: query
            - name: up_right_lng
              description: -180 to 180
              paramType: query
        """
        shouts = self.filter_queryset(self.get_index_search())
        page = self.paginate_queryset(shouts)
        serializer = self.get_serializer(page, many=True)
        result = self.get_paginated_response(serializer.data)

        # Todo: add actual data
        result.data['web_url'] = settings.SITE_LINK + 'search?src=api'
        result.data['related_searches'] = []

        # Track, skip when requests shouts of a Profile, Tag or Discover
        search_data = getattr(shouts, 'search_data', {})
        if not any_in(['profile', 'tag', 'discover'], search_data.keys()):
            search_data.update({
                'num_results':
                result.data.get('count'),
                'api_client':
                getattr(request, 'api_client', None),
                'api_version':
                request.version,
            })
            event_name = 'search' if 'search' in search_data else 'browse'
            mixpanel_controller.track(request.user.pk, event_name, search_data)
        return result
Example #7
0
def post_save_listen(sender, instance=None, created=False, **kwargs):
    from shoutit.controllers import mixpanel_controller
    if created:
        mixpanel_controller.track(instance.user.pk, 'new_listen',
                                  instance.track_properties)
Example #8
0
    def list(self, request, *args, **kwargs):
        """
        List shouts.
        [Shouts Pagination](https://docs.google.com/document/d/1Zp9Ks3OwBQbgaDRqaULfMDHB-eg9as6_wHyvrAWa8u0/edit#heading=h.97r3lxfv95pj)
        ###Response
        <pre><code>
        {
          "next": null, // next results page url
          "previous": null, // previous results page url
          "results": [] // list of {ShoutSerializer}
          "related_searches": [] // list of keywords related to the current search [currently dummy text is being returned]
        }
        </code></pre>
        ---
        serializer: ShoutSerializer
        parameters:
            - name: search
              description: space or comma separated keywords to search in title, text, tags
              paramType: query
            - name: shout_type
              paramType: query
              defaultValue: all
              enum:
                - request
                - offer
                - all
            - name: country
              paramType: query
            - name: city
              paramType: query
            - name: min_price
              type: float
              paramType: query
              type: float
            - name: max_price
              paramType: query
            - name: down_left_lat
              description: -90 to 90, can not be greater than up_right_lat
              type: float
              paramType: query
            - name: down_left_lng
              description: -180 to 180, can not be greater than up_right_lng
              type: float
              paramType: query
            - name: up_right_lat
              description: -90 to 90
              type: float
              paramType: query
            - name: up_right_lng
              description: -180 to 180
              type: float
              paramType: query
            - name: category
              description: the category name
              paramType: query
            - name: tags
              description: space or comma separated tags. returned shouts will contain ALL of them. passing single tag is also possible to list its shouts
              paramType: query
            - name: discover
              description: discover item id to list its shouts
              paramType: query
            - name: user
              description: user username to list his shouts
              paramType: query
        """
        shouts = self.filter_queryset(self.get_index_search())
        page = self.paginate_queryset(shouts)
        serializer = self.get_serializer(page, many=True)
        result = self.get_paginated_response(serializer.data)
        result.data['related_searches'] = [
            'HP', 'Laptops', 'Lenovo', 'Macbook Pro'
        ]

        # Track, skip when requests shouts of a Profile, Tag or Discover
        search_data = getattr(shouts, 'search_data', {})
        if not any_in(['user', 'tag', 'discover'], search_data.keys()):
            search_data.update({
                'num_results':
                result.data.get('count'),
                'api_client':
                getattr(request, 'api_client', None),
                'api_version':
                request.version,
            })
            event_name = 'search' if 'search' in search_data else 'browse'
            mixpanel_controller.track(request.user.pk, event_name, search_data)
        return result
Example #9
0
def shout_bookmark_post_save(sender, instance=None, created=False, **kwargs):
    if created:
        # Track
        mixpanel_controller.track(instance.user.pk, 'new_shout_bookmark',
                                  instance.track_properties)