Beispiel #1
0
class EventMessageResource(WigoResource):
    model = EventMessage

    @user_token_required
    @api.response(200, 'Success', model=EventMessage.to_doc_list_model(api))
    def get(self, event_id, message_id):
        message = self.model.find(self.get_id(message_id))
        event = message.event
        if not g.user.can_see_event(event):
            abort(403, message='Can not see event')
        return self.serialize_list(self.model, [message])

    @user_token_required
    @api.expect(EventMessage.to_doc_list_model(api))
    @api.response(200, 'Success', model=EventMessage.to_doc_list_model(api))
    def post(self, event_id, message_id):
        message = self.edit(message_id, request.get_json())
        return self.serialize_list(self.model, [message])

    @user_token_required
    def delete(self, event_id, message_id):
        message = self.model.find(self.get_id(message_id))
        self.check_edit(message)
        message.delete()
        return {'success': True}
Beispiel #2
0
def tell_friend_delete_event_message(user_id, event_id, message_id, friend_id):
    try:
        friend = User.find(friend_id)
    except DoesNotExist:
        return

    message = EventMessage({
        'id': message_id,
        'user_id': user_id,
        'event_id': event_id
    })

    message.remove_for_user(friend)
Beispiel #3
0
def notify_on_eventmessage_vote(voter_id, message_id):
    try:
        voter = User.find(voter_id)
        message = EventMessage.find(message_id)
    except DoesNotExist:
        return

    user = message.user
    type = 'video' if message.media_mime_type == 'video/mp4' else 'photo'

    # don't send to self or if not friend
    if (voter_id == message.user_id) or (not user.is_friend(voter_id)):
        return

    with rate_limit('notify:vote:%s:%s:%s' % (message.user_id, message_id, voter_id),
                    timedelta(hours=2)) as limited:
        if not limited:
            message_text = '{name} liked your {type} in {event}'.format(
                name=voter.full_name.encode('utf-8'),
                type=type,
                event=message.event.name.encode('utf-8'))

            notification = Notification({
                'user_id': message.user_id,
                'type': 'eventmessage.vote',
                'from_user_id': voter_id,
                'navigate': '/users/me/events/{}/messages/{}'.format(message.event_id, message.id),
                'message': message_text
            }).save()

            send_notification_push.delay(notification.to_primitive())
Beispiel #4
0
def on_thumbnail_upload(key):
    if key != Configuration.API_HOOK_KEY:
        abort(400, message='Invalid api key')

    data = request.data or request.form.get('results') or ''
    try:
        data = ujson.loads(data)
    except ValueError:
        logger.error('error parsing blitline callback data, {data}'.format(data=data))
        abort(400, message='Bad json data')

    images = data.get('images')
    errors = data.get('errors')

    if images:
        for image in images:
            type_and_id = ujson.loads(image.get('image_identifier'))
            s3_path = urlparse(image.get('s3_url')).path.replace('/wigo-uploads/', '')
            if type_and_id['type'] == 'EventMessage':
                message = EventMessage.find(type_and_id['id'])
                if type_and_id.get('thumbnail') is not False:
                    message.thumbnail = s3_path
                else:
                    message.media = s3_path
                message.save()

        return jsonify(success=True)
    else:
        failed_ids = data.get('failed_image_identifiers')
        logger.error('error creating thumbnail for {ids}, {error}'.format(ids=failed_ids, error=errors))
        return jsonify(success=False)
Beispiel #5
0
def tell_friend_event_message(message_id, friend_id):
    try:
        message = EventMessage.find(message_id)
        friend = User.find(friend_id)
    except DoesNotExist:
        return

    message.record_for_user(friend)
Beispiel #6
0
    def get(self, event_id, message_id, headers):
        from server.models.user import User

        event = Event.find(event_id)
        if not g.user.can_see_event(event):
            abort(403, message='Can not see event')
        message = EventMessage.find(message_id)
        count, page, votes = self.select().eventmessage(message).execute()
        return self.serialize_list(User, votes, count, page), 200, headers
Beispiel #7
0
def test_event_messages():
    from server.models.event import Event
    from server.models.user import User

    with client() as c:
        user1 = User.find(key='test')
        user2 = User.find(key='test2')
        event_id = create_event(c, user1, 'e1')
        event = Event.find(event_id)

        create_event_message(c, user1, event, 'test.jpg')
        assert 1 == EventMessage.select().event(event).count()
        assert 1 == EventMessage.select().event(event).user(user1).count()
        assert 0 == EventMessage.select().event(event).user(user2).count()

        make_friends(c, user1, user2)

        assert 1 == EventMessage.select().event(event).user(user2).count()
Beispiel #8
0
def tell_friends_event_message(message_id):
    try:
        message = EventMessage.find(message_id)
        user_id = message.user_id
    except:
        return
    for friend_id, score in wigo_db.sorted_set_iter(
            skey('user', user_id, 'friends')):
        tell_friend_event_message.delay(message_id, friend_id)
Beispiel #9
0
def test_event_message_votes():
    from server.models.event import Event
    from server.models.user import User
    from server.db import wigo_db

    with client() as c:
        user1 = User.find(key='test')
        user2 = User.find(key='test2')
        user3 = User.find(key='test3')

        make_friends(c, user2, user3)

        event_id = create_event(c, user1, 'e1')
        event = Event.find(event_id)

        message_id_1 = create_event_message(c, user1, event, 'test.jpg')
        message_id_2 = create_event_message(c, user1, event, 'test.jpg')

        message_1 = EventMessage.find(message_id_1)
        message_2 = EventMessage.find(message_id_2)

        resp = create_event_message_vote(c, user1, event, message_1)
        resp = create_event_message_vote(c, user2, event, message_2)
        resp = create_event_message_vote(c, user3, event, message_2)

        assert wigo_db.get_sorted_set_size(skey(message_1, 'votes')) == 1
        assert wigo_db.get_sorted_set_size(skey(message_2, 'votes')) == 2

        assert EventMessage.select().event(event).by_votes().get() == message_2

        resp = api_get(c, user1,
                       '/api/events/{}/messages/meta'.format(event_id))
        data = ujson.loads(resp.data)
        assert 1 == data[str(message_id_1)]['num_votes']

        make_friends(c, user1, user2)

        make_friends(c, user1, user3)

        resp = create_event_message_vote(c, user2, event, message_1)
        resp = create_event_message_vote(c, user3, event, message_1)

        assert EventMessage.select().event(event).by_votes().get() == message_1
Beispiel #10
0
 def post(self, event_id, message_id):
     try:
         message = EventMessage.find(message_id)
         EventMessageVote({
             'message_id': message_id,
             'user_id': g.user.id
         }).save()
         return {'success': True}
     except DoesNotExist:
         abort(400, message='Event message missing, probably deleted')
Beispiel #11
0
    def delete_history(u, f):
        with wigo_db.transaction(commit_on_select=False):
            for message in EventMessage.select().key(skey(u,
                                                          'event_messages')):
                if message.user and message.event:
                    message.remove_for_user(f)

        for event in Event.select().user(u):
            if wigo_db.sorted_set_is_member(user_attendees_key(f, event),
                                            u.id):
                event.remove_from_user_attending(f, u)
Beispiel #12
0
    def capture_history(u, f):
        # capture each of the users posted photos
        with wigo_db.transaction(commit_on_select=False):
            for message in EventMessage.select().key(skey(
                    u, 'event_messages')).min(min):
                if message.user and message.event:
                    message.record_for_user(f)

        # capture the events being attended
        for event in Event.select().user(u).min(min):
            if u.is_attending(event) and f.can_see_event(event):
                event.add_to_user_attending(f, u)
Beispiel #13
0
    def annotate_events(self, events):
        alimit = int(request.args.get('attendees_limit', 5))
        mlimit = int(request.args.get('messages_limit', 5))

        current_user = g.user
        user_context = current_user if '/users/' in request.path else None

        # fill in attending on each event
        query = EventAttendee.select().events(events).user(user_context).secure(g.user)
        count, page, attendees_by_event = query.limit(alimit).execute()
        if count:
            for event, attendees in zip(events, attendees_by_event):
                # make sure the event the current user is attending is in front
                if hasattr(event, 'current_user_attending'):
                    count, attendees = attendees
                    if attendees and attendees[0] != g.user:
                        if g.user in attendees:
                            attendees.remove(g.user)
                        attendees.insert(0, g.user)
                    attendees = (count, attendees)

                event.attendees = attendees
                event.num_attending = attendees[0]

        def capture_messages(events, query):
            count, page, messages_by_event = query.limit(mlimit).execute()
            if count:
                for event, messages in zip(events, messages_by_event):
                    event.messages = messages

        base_query = EventMessage.select().user(user_context).secure(g.user)
        capture_messages(events, base_query.events(events))

        # expired, current = partition(events, lambda e: e.is_expired)
        # base_query = EventMessage.select().user(user_context).secure(g.user)
        # capture_messages(current, base_query.events(current))
        # capture_messages(expired, base_query.events(expired).by_votes())

        filtered = []
        for event in events:
            include_event = True
            if not hasattr(event, 'attendees') or len(event.attendees[1]) == 0:
                include_event = False
            if event.is_expired:
                if not hasattr(event, 'messages') or len(event.messages[1]) == 0:
                    include_event = False
            if include_event:
                filtered.append(event)

        return filtered
Beispiel #14
0
class UserEventMessageListResource(WigoResource):
    model = EventMessage

    @user_token_required
    @check_last_modified('user', 'last_event_change')
    @api.response(200, 'Success', model=EventMessage.to_doc_list_model(api))
    def get(self, user_id, event_id, headers):
        event = Event.find(event_id)
        if not g.user.can_see_event(event):
            abort(403, message='Can not see event')
        query = self.select().event(event).user(g.user).secure(g.user)
        # if event.is_expired:
        #     query = query.by_votes()
        count, page, messages = query.execute()
        return self.serialize_list(self.model, messages, count, page), 200, headers
Beispiel #15
0
class EventMessageListResource(WigoResource):
    model = EventMessage

    @user_token_required
    @check_last_modified('group', 'last_event_change')
    @api.response(200, 'Success', model=EventMessage.to_doc_list_model(api))
    def get(self, event_id, headers):
        event = Event.find(event_id)
        if not g.user.can_see_event(event):
            abort(403, message='Can not see event')
        query = self.select().event(event).secure(g.user)
        # if event.is_expired:
        #     query = query.by_votes()
        count, page, messages = query.execute()
        return self.serialize_list(self.model, messages, count, page), 200, headers

    @user_token_required
    @api.expect(EventMessage.to_doc_list_model(api))
    @api.response(200, 'Success', model=Event.to_doc_list_model(api))
    def post(self, event_id):
        data = dict(request.get_json())
        data['event_id'] = event_id
        message = self.create(data)
        return self.serialize_list(self.model, [message])
Beispiel #16
0
class UserEventMessagesMetaListResource(WigoResource):
    model = EventMessage

    @user_token_required
    @check_last_modified('user', 'last_event_change')
    @api.response(200, 'Success', model=EventMessage.to_doc_list_model(api))
    def get(self, user_id, event_id, headers):
        message_meta = {}

        message_ids = wigo_db.sorted_set_range(user_eventmessages_key(g.user, event_id))
        for message_id in message_ids:
            message_meta[message_id] = {
                'num_votes': wigo_db.get_sorted_set_size(user_votes_key(g.user, message_id)),
                'voted': wigo_db.sorted_set_is_member(user_votes_key(g.user, message_id), g.user.id)
            }

        return message_meta, 200, headers
Beispiel #17
0
def notify_on_eventmessage(message_id):
    try:
        message = EventMessage.find(message_id)
    except DoesNotExist:
        return

    user = message.user

    if message.event.is_expired:
        return

    type = 'video' if message.media_mime_type == 'video/mp4' else 'photo'

    for friend in EventAttendee.select().user(message.user).event(message.event):
        if friend == user:
            continue

        with rate_limit('notify:eventmessage:{}:{}:{}'.format(user.id, message.event.id, friend.id),
                        timedelta(hours=2)) as limited:
            if limited:
                return

            message_text = '{name} posted a {type} in {event}'.format(
                name=user.full_name.encode('utf-8'),
                type=type,
                event=message.event.name.encode('utf-8'))

            notification = Notification({
                'user_id': friend.id,
                'type': 'eventmessage.post',
                'from_user_id': message.user_id,
                'navigate': '/users/me/events/{}/messages/{}'.format(message.event_id, message.id),
                'message': message_text
            }).save()

            send_notification_push.delay(notification.to_primitive())
Beispiel #18
0
def process_eventmessage_image(message_id):
    if not Configuration.BLITLINE_APPLICATION_ID:
        logger.warning('blitline not configured, ignoring thumbnail request')
        return

    try:
        message = EventMessage.find(message_id)
    except DoesNotExist:
        return

    if message.media_mime_type == 'video/mp4':
        media = message.image
        if media is None and message.thumbnail:
            media = message.thumbnail
            message.image = media
            message.thumbnail = None
            message.save()
    else:
        media = message.media

    if not media:
        return

    path = os.path.split(urlparse(media).path)[0]

    function = {
        'name': 'resize_to_fit',
        'params': {
            'width': 150
        },
        'save': {
            'image_identifier':
            ujson.dumps({
                'type': 'EventMessage',
                'id': message.id,
                'thumbnail': True
            }),
            's3_destination': {
                'bucket': 'wigo-uploads',
                'key': path + '/' + str(message.id) + '-thumb.jpg',
                'headers': {
                    'Content-Type': 'image/jpeg',
                    'Cache-Control': 'max-age=86400'
                }
            }
        }
    }

    # the hook is defined in uploads.py
    job_data = {
        'application_id':
        Configuration.BLITLINE_APPLICATION_ID,
        'src':
        'https://' + Configuration.UPLOADS_CDN + '/' + media,
        'postback_url':
        'https://' + Configuration.API_HOST + '/api/hooks/blitline/' +
        Configuration.API_HOOK_KEY + '/',
        'functions': [function]
    }

    resp = requests.post('http://api.blitline.com/job',
                         data={'json': ujson.dumps(job_data)},
                         timeout=10)

    if resp.status_code == 200:
        json = resp.json()
        if 'error' in json:
            error_str = 'error creating blitline thumbnail job for ' \
                        'event message {id}, {error}'.format(id=message.id, error=json.get('error'))
            logger.error(error_str)
            raise Exception(error_str)
    else:
        error_str = 'error creating blitline thumbnail job ' \
                    'for event message {id}, {error}'.format(id=message.id, error=resp.content)
        logger.error(error_str)
        raise Exception(error_str)
Beispiel #19
0
def delete_user(user_id, group_id):
    logger.info('deleting user {}'.format(user_id))

    friend_ids = wigo_db.sorted_set_range(skey('user', user_id, 'friends'))

    with wigo_db.transaction(commit_on_select=False):
        # remove from attendees
        for event_id, score in wigo_db.sorted_set_iter(
                skey('user', user_id, 'events')):
            wigo_db.sorted_set_remove(skey('event', event_id, 'attendees'),
                                      user_id)
            for friend_id in friend_ids:
                wigo_db.sorted_set_remove(
                    skey('user', friend_id, 'event', event_id, 'attendees'),
                    user_id)

        # remove event message votes
        for message_id, score in wigo_db.sorted_set_iter(
                skey('user', user_id, 'votes')):
            wigo_db.sorted_set_remove(
                skey('eventmessage', message_id, 'votes'), user_id)
            for friend_id in friend_ids:
                wigo_db.sorted_set_remove(
                    user_votes_key(friend_id, message_id), user_id)

        # remove event messages
        for message_id, score in wigo_db.sorted_set_iter(
                skey('user', user_id, 'event_messages')):
            message = EventMessage.find(message_id)
            event_id = message.event_id
            wigo_db.sorted_set_remove(skey('event', event_id, 'messages'),
                                      message_id)
            wigo_db.sorted_set_remove(
                skey('event', event_id, 'messages', 'by_votes'), message_id)
            for friend_id in friend_ids:
                wigo_db.sorted_set_remove(
                    skey('user', friend_id, 'event', event_id, 'messages'),
                    message_id)
                wigo_db.sorted_set_remove(
                    skey('user', friend_id, 'event', event_id, 'messages',
                         'by_votes'), message_id)

        for friend_id in friend_ids:
            # remove conversations
            wigo_db.sorted_set_remove(skey('user', friend_id, 'conversations'),
                                      user_id)
            wigo_db.delete(skey('user', friend_id, 'conversation', user_id))
            wigo_db.delete(skey('user', user_id, 'conversation', friend_id))

            # remove friends
            wigo_db.sorted_set_remove(skey('user', friend_id, 'friends'),
                                      user_id)
            wigo_db.sorted_set_remove(
                skey('user', friend_id, 'friends', 'top'), user_id)
            wigo_db.sorted_set_remove(
                skey('user', friend_id, 'friends', 'alpha'), user_id)
            wigo_db.set_remove(skey('user', friend_id, 'friends', 'private'),
                               user_id)

        # remove friend requests
        for friend_id in wigo_db.sorted_set_range(
                skey('user', user_id, 'friend_requested')):
            wigo_db.sorted_set_remove(
                skey('user', friend_id, 'friend_requests'), user_id)
            wigo_db.sorted_set_remove(
                skey('user', friend_id, 'friend_requests', 'common'), user_id)

        # remove messages
        for message_id, score in wigo_db.sorted_set_iter(
                skey('user', user_id, 'messages')):
            wigo_db.delete(skey('message', message_id))

        wigo_db.delete(skey('user', user_id, 'events'))
        wigo_db.delete(skey('user', user_id, 'friends'))
        wigo_db.delete(skey('user', user_id, 'friends', 'top'))
        wigo_db.delete(skey('user', user_id, 'friends', 'private'))
        wigo_db.delete(skey('user', user_id, 'friends', 'alpha'))
        wigo_db.delete(skey('user', user_id, 'friends', 'friend_requested'))
        wigo_db.delete(skey('user', user_id, 'friends', 'friend_requests'))
        wigo_db.delete(
            skey('user', user_id, 'friends', 'friend_requests', 'common'))
        wigo_db.delete(skey('user', user_id, 'blocked'))
        wigo_db.delete(skey('user', user_id, 'notifications'))
        wigo_db.delete(skey('user', user_id, 'notifs'), replicate=False)
        wigo_db.delete(skey('user', user_id, 'conversations'))
        wigo_db.delete(skey('user', user_id, 'tapped'))
        wigo_db.delete(skey('user', user_id, 'votes'))
        wigo_db.delete(skey('user', user_id, 'messages'))