示例#1
0
def test_create_event():
    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')

        create_event(c, user1, 'test event')

        resp = api_get(c, user1, '/api/events/')
        assert resp.status_code == 200, 'oops {}'.format(resp.data)
        data = ujson.loads(resp.data)
        assert data['objects'][0]['name'] == 'test event'
        assert data['objects'][0]['group'] == {'$ref': 'Group:1'}

        event_id = data['objects'][0]['id']
        event = Event.find(event_id)
        assert user1.is_attending(event), 'user is attending the new event'
        assert 1 == Event.select().count()

        event_id = create_event(c, user1, 'test event 2')
        user1 = User.find(key='test')
        assert user1.get_attending_id() == event_id
        assert 2 == Event.select().count(), '2 events total now'
        count, page, results = Event.select().group(user1.group).execute()
        assert 1 == count, 'only 1 in the group though, since the other has no attendees now'
        assert results[0].name == 'test event 2'
示例#2
0
    def post(self):
        json = request.get_json()
        if 'city_id' in json:
            group = get_group_by_city_id(json['city_id'])
        elif 'group_id' in json:
            group = Group.find(json['group_id'])
        else:
            group = g.group

        try:
            event = Event({
                'name': json.get('name'),
                'group_id': group.id,
                'owner_id': g.user.id,
                'privacy': json.get('privacy') or 'public'
            })

            if 'date' in json:
                date = parse(json.get('date'))
                event.date = group.get_day_start(date)
                event.expires = group.get_day_end(date)
            else:
                event.date = group.get_day_start()
                event.expires = group.get_day_end()

            if 'latitude' in json:
                event.latitude = json.get('latitude')
            if 'longitude' in json:
                event.longitude = json.get('longitude')

            event.save()
            return self.serialize_list(Event, [event])
        except AlreadyExistsException, e:
            return self.handle_already_exists_exception(e)
示例#3
0
class UserEventListResource(WigoResource):
    model = Event

    def get_limit(self, default=5):
        return super(UserEventListResource, self).get_limit(default)

    @user_token_required
    @check_last_modified('user', 'last_event_change')
    @api.response(200, 'Success', model=Event.to_doc_list_model(api))
    def get(self, user_id, headers):
        user = g.user
        group = g.group

        query = self.select().user(user)
        query = query.min(epoch(group.get_day_end() - timedelta(days=8)))
        query = query.max(epoch(group.get_day_end() + timedelta(hours=4)))

        count, page, events = query.execute()

        attending_id = user.get_attending_id()
        if attending_id:
            try:
                attending = Event.find(attending_id)
                if attending in events:
                    events.remove(attending)
                if 'page' not in request.args:
                    events.insert(0, attending)
                    attending.current_user_attending = True
            except DoesNotExist:
                logger.warn('Event {} not found'.format(attending_id))

        return self.serialize_list(self.model, events, count, page), 200, headers
示例#4
0
def notify_on_friend_attending(event_id, user_id, friend_id):
    num_attending = get_num_attending(event_id, user_id)
    if num_attending < 5:
        return

    try:
        event = Event.find(event_id)
        user = User.find(user_id)
    except DoesNotExist:
        return

    if event.is_expired:
        return

    rl_key = 'notify:nofa:{}:{}'.format(event_id, user_id)
    with rate_limit(rl_key, event.expires) as limited:
        if not limited:
            friends = list(islice(EventAttendee.select().event(event).user(user).limit(6), 5))
            if user in friends:
                friends.remove(user)
                num_attending -= 1

            logger.info('notifying user {} of {} friends attending event {}'.format(user_id, num_attending, event_id))
            if len(friends) >= 2:
                notification = Notification({
                    'user_id': user.id,
                    'type': 'system',
                    'navigate': '/users/me/events/{}'.format(event_id),
                    'badge': 1,
                    'message': '{}, {}, and {} others are going to {}'.format(
                        friends[0].full_name.encode('utf-8'), friends[1].full_name.encode('utf-8'),
                        num_attending - 2, event.name.encode('utf-8'))
                }).save()

                send_notification_push.delay(notification.to_primitive())
示例#5
0
 def post(self, application_id):
     args = self.reqparse.parse_args()
     args['application_id'] = application_id
     event = Event(args)
     db.session.add(event)
     db.session.commit()
     return 'Event added!', 201
示例#6
0
    def get(self, headers):
        user = g.user
        group = g.group

        query = self.select().group(group)
        query = query.min(epoch(group.get_day_end() - timedelta(days=8)))
        query = query.max(epoch(group.get_day_end() + timedelta(hours=4)))
        count, page, events = query.execute()

        if count == 0 and group.status == 'initializing':
            tries = int(request.args.get('tries', 0))
            if tries < 5:
                sleep(1)  # clients seem to not obey Retry-After, so artificially delay
                request_arguments = request.args.copy().to_dict()
                request_arguments['tries'] = tries
                response = redirect('%s?%s' % (request.path, url_encode(request_arguments)))
                response.headers.add('Retry-After', 1)
                return response
            else:
                # return without "headers" so this response isn't cached
                return self.serialize_list(self.model, events, count, page), 200

        attending_id = g.user.get_attending_id()
        if attending_id:
            try:
                attending = Event.find(attending_id)
                if attending in events:
                    events.remove(attending)
                if 'page' not in request.args:
                    events.insert(0, attending)
                    attending.current_user_attending = True
            except DoesNotExist:
                logger.warn('Event {} not found'.format(attending_id))

        return self.serialize_list(self.model, events, count, page), 200, headers
示例#7
0
def notify_on_attendee(event_id, user_id):
    try:
        event = Event.find(event_id)
        user = User.find(user_id)
        if event.owner is None:
            return
    except DoesNotExist:
        return

    if event.is_expired or not user.is_attending(event):
        return

    targets = [5, 10, 20, 30, 50, 75, 100, 150, 200, 250, 300, 350, 400, 450, 500]
    num_attending = get_num_attending(event_id)
    target = next(reversed([t for t in targets if t <= num_attending]), None)

    if target is None:
        return

    rl_key = 'notify:event_creators:{}:{}:{}'.format(event.id, event.owner_id, target)
    with rate_limit(rl_key, event.expires) as limited:
        if not limited:
            notification = Notification({
                'user_id': event.owner_id,
                'type': 'system',
                'navigate': '/events/{}'.format(event_id),
                'badge': 1,
                'message': '{} people are going to your event {}'.format(
                    num_attending, event.name.encode('utf-8'))
            }).save()

            send_notification_push.delay(notification.to_primitive())
示例#8
0
 def event(self):
     if self.event_id:
         from server.models.event import Event
         try:
             return Event.find(self.event_id)
         except DoesNotExist:
             logger.warn('event {} not found'.format(self.event_id))
     return None
示例#9
0
 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
示例#10
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
示例#11
0
def tell_friends_user_not_attending(user_id, event_id):
    try:
        user = User.find(user_id)
        event = Event.find(event_id)
    except DoesNotExist:
        return

    if not user.is_attending(event):
        for friend_id, score in wigo_db.sorted_set_iter(skey(user, 'friends')):
            tell_friend_user_not_attending.delay(user_id, event_id, friend_id)
示例#12
0
def tell_friend_user_not_attending(user_id, event_id, friend_id):
    try:
        user = User.find(user_id)
        event = Event.find(event_id)
        friend = User.find(friend_id)
    except DoesNotExist:
        return

    if not user.is_attending(event):
        event.remove_from_user_attending(friend, user)
示例#13
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)
示例#14
0
def tell_friends_user_attending(user_id, event_id, notify=True):
    try:
        user = User.find(user_id)
        event = Event.find(event_id)
    except DoesNotExist:
        return

    if user.is_attending(event):
        for friend in user.friends_iter():
            if friend.can_see_event(event):
                tell_friend_user_attending.delay(user_id, event_id, friend.id,
                                                 notify)
示例#15
0
def tell_friend_user_attending(user_id, event_id, friend_id, notify=True):
    try:
        user = User.find(user_id)
        event = Event.find(event_id)
        friend = User.find(friend_id)
    except DoesNotExist:
        return

    if user.is_attending(event):
        event.add_to_user_attending(friend, user)
        if notify:
            friend_attending.send(None, event=event, user=friend, friend=user)
示例#16
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)
示例#17
0
def user_invited(event_id, inviter_id, invited_id):
    try:
        event = Event.find(event_id)
        inviter = User.find(inviter_id)
        invited = User.find(invited_id)
    except DoesNotExist:
        return

    # make sure i am seeing all my friends attending now
    for friend in invited.friends_iter():
        if friend.is_attending(event):
            event.add_to_user_attending(invited, friend)
示例#18
0
def test_user_events():
    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')

        create_event(c, user1, 'test event 1')
        create_event(c, user2, 'test event 2')

        assert 2 == Event.select().count(), '2 events total now'
        assert 2 == Event.select().group(user1.group).count()

        count, page, results = Event.select().user(user1).execute()
        assert 1 == count
        assert results[0].name == 'test event 1'

        count, page, results = Event.select().user(user2).execute()
        assert 1 == count
        assert results[0].name == 'test event 2'
示例#19
0
def test_private_event():
    from server.models.event import Event, EventAttendee
    from server.models.user import User

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

        event_id = create_event(c, user1, 'test event 1', privacy='private')

        assert 1 == Event.select().count()
        assert 0 == Event.select().group(user1.group).count()
        assert 1 == Event.select().user(user1).count()
        assert 0 == Event.select().user(user2).count()

        event = Event.find(event_id)

        resp = api_post(c, user1, '/api/events/{}/invites'.format(event_id),
                        {'invited_id': user2.id})

        assert resp.status_code == 200, 'oops {}'.format(resp.data)
        assert 1 == Event.select().user(user2).count()
        count, page, results = EventAttendee.select().event(event).user(
            user2).execute()
        assert count == 1
        assert results[0] == user1
示例#20
0
class EventResource(WigoDbResource):
    model = Event

    @user_token_required
    @api.response(200, 'Success', model=Event.to_doc_list_model(api))
    def get(self, model_id):
        return super(EventResource, self).get(model_id)

    def check_get(self, event):
        super(EventResource, self).check_get(event)
        if not g.user.can_see_event(event):
            abort(403, message='Can not see event event')

    @user_token_required
    @api.expect(Event.to_doc_list_model(api))
    @api.response(200, 'Success', model=Event.to_doc_list_model(api))
    def post(self, model_id):
        return super(EventResource, self).post(model_id)

    @api.response(501, 'Not implemented')
    def delete(self, model_id):
        abort(501, message='Not implemented')
示例#21
0
def new_group(group_id):
    group = Group.find(group_id)
    logger.info('new group {} created, importing events'.format(
        group.name.encode('utf-8')))
    num_imported = 0
    imported = set()

    min = epoch(group.get_day_end() - timedelta(days=7))

    with wigo_db.transaction(commit_on_select=False):
        for close_group in get_close_groups(group.latitude, group.longitude,
                                            100):
            if close_group.id == group.id:
                continue

            for event in Event.select().group(close_group).min(min):
                # only import the events the group actually owns
                if event.group_id != close_group.id:
                    continue
                # no double imports
                if event.id not in imported:
                    event.update_global_events(group=group)
                    imported.add(event.id)
                    num_imported += 1

        for event in Event.select().key(skey('global', 'events')).min(min):
            if event.id not in imported:
                event.update_global_events(group=group)
                imported.add(event.id)
                num_imported += 1

    logger.info('imported {} events into group {}'.format(
        num_imported, group.name.encode('utf-8')))
    group.track_meta('last_event_change', expire=None)
    group.status = 'active'
    group.save()
示例#22
0
class FutureUserEventListResource(WigoResource):
    model = Event

    @user_token_required
    @check_last_modified('user', 'last_event_change')
    @api.response(200, 'Success', model=Event.to_doc_list_model(api))
    def get(self, user_id, headers):
        user = g.user
        group = g.group

        query = self.select().user(user).order('asc')
        query = query.min(epoch(group.get_day_start()))
        query = query.max(epoch(group.get_day_end() + timedelta(days=10)))
        count, page, instances = query.execute()

        return self.serialize_list(self.model, instances, count, page), 200, headers
示例#23
0
class FutureEventListResource(WigoDbListResource):
    model = Event

    def get_limit(self, default=10):
        return super(FutureEventListResource, self).get_limit(default)

    @user_token_required
    @check_last_modified('group', 'last_event_change')
    @api.response(200, 'Success', model=Event.to_doc_list_model(api))
    def get(self, headers):
        user = g.user
        group = g.group
        query = self.select().group(group).order('asc')
        query = query.min(epoch(group.get_day_start()))
        query = query.max(epoch(group.get_day_end() + timedelta(days=10)))
        count, page, events = query.execute()
        return self.serialize_list(self.model, events, count, page), 200, headers
示例#24
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()
示例#25
0
class FutureEventMetaListResource(WigoResource):
    @user_token_required
    @check_last_modified('group', 'last_event_change')
    @api.response(200, 'Success', model=Event.to_doc_list_model(api))
    def get(self, headers):
        group = g.group
        meta = {}

        dates = [(group.get_day_end() + timedelta(days=i)) for i in range(10)]

        p = wigo_db.redis.pipeline()
        for d in dates:
            p.zcount(skey(group, 'events'), epoch(d), epoch(d + timedelta(hours=3)))
        counts = p.execute()

        for index, d in enumerate(dates):
            meta[(d - timedelta(days=1)).date().isoformat()] = counts[index]

        return meta, 200, headers
示例#26
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
示例#27
0
    def get(self, event_id):
        event = Event.find(event_id)

        page = self.get_page()
        limit = self.get_limit()
        start = (page - 1) * limit

        num_friends = wigo_db.get_sorted_set_size(skey(g.user, 'friends'))

        # find the users top 5 friends. this is users with > 3 interactions
        top_5 = wigo_db.sorted_set_rrange_by_score(skey(
            g.user, 'friends', 'top'),
                                                   'inf',
                                                   3,
                                                   limit=5)
        if not top_5:
            top_5 = wigo_db.sorted_set_rrange_by_score(skey(g.user, 'friends'),
                                                       'inf',
                                                       3,
                                                       limit=5)

        friend_ids = wigo_db.sorted_set_range(skey(g.user, 'friends', 'alpha'),
                                              start, start + (limit - 1))
        for top_friend_id in top_5:
            if top_friend_id in friend_ids:
                friend_ids.remove(top_friend_id)

        if page == 1 and top_5:
            friend_ids = top_5 + friend_ids

        users = User.find(friend_ids)

        p = wigo_db.redis.pipeline()
        for user in users:
            p.zscore(skey(event, g.user, 'invited'), user.id if user else -1)

        scores = p.execute()
        for index, user in enumerate(users):
            if user:
                user.invited = scores[index] is not None

        return self.serialize_list(self.model, users, num_friends, page)
示例#28
0
def notify_on_invite(inviter_id, invited_id, event_id):
    rl_key = 'notify:invite:{}:{}:{}'.format(inviter_id, invited_id, event_id)
    with rate_limit(rl_key, timedelta(hours=2)) as limited:
        if not limited:
            inviter = User.find(inviter_id)
            invited = User.find(invited_id)
            event = Event.find(event_id) if event_id else None

            message_text = '{} invited you out to {}'.format(inviter.full_name.encode('utf-8'),
                                                             event.name.encode('utf-8'))

            notification = Notification({
                'user_id': invited_id,
                'type': 'invite',
                'from_user_id': inviter_id,
                'navigate': '/users/me/events/{}'.format(event_id),
                'badge': 1,
                'message': message_text
            }).save()

            send_notification_push.delay(notification.to_primitive())
示例#29
0
def test_attending():
    from server.models.event import Event, EventAttendee
    from server.models.user import User

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

        create_event(c, user1, 'test event 1')
        event = Event.find(name='test event 1', group=user1.group)

        resp = api_post(c, user2, '/api/events/{}/attendees'.format(event.id),
                        {})
        assert resp.status_code == 200, 'oops {}'.format(resp.data)

        assert 2 == EventAttendee.select().event(event).count()
        assert 1 == EventAttendee.select().event(event).user(user1).count()
        assert 1 == EventAttendee.select().event(event).user(user2).count()

        make_friends(c, user1, user2)

        assert 2 == EventAttendee.select().event(event).user(user1).count()
示例#30
0
    def get(self, user_id, headers):
        user = g.user
        group = g.group

        query = self.select().user(user)
        query = query.min(epoch(group.get_day_end() - timedelta(days=8)))
        query = query.max(epoch(group.get_day_end() + timedelta(hours=4)))

        count, page, events = query.execute()

        attending_id = user.get_attending_id()
        if attending_id:
            try:
                attending = Event.find(attending_id)
                if attending in events:
                    events.remove(attending)
                if 'page' not in request.args:
                    events.insert(0, attending)
                    attending.current_user_attending = True
            except DoesNotExist:
                logger.warn('Event {} not found'.format(attending_id))

        return self.serialize_list(self.model, events, count, page), 200, headers