def delete_conversation(cls, user, to_user): from server.db import wigo_db with wigo_db.transaction(commit_on_select=False): wigo_db.sorted_set_remove(skey(user, 'conversations'), to_user.id) wigo_db.delete(skey(user, 'conversation', to_user.id)) user.track_meta('last_message_change') to_user.track_meta('last_message_change')
def privacy_changed(user_id): # tell all friends about the privacy change user = User.find(user_id) with wigo_db.transaction(commit_on_select=False): for friend in user.friends_iter(): if user.privacy == 'public': wigo_db.set_remove(skey(friend, 'friends', 'private'), user_id) else: wigo_db.set_add(skey(friend, 'friends', 'private'), user_id)
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)
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)
def check_active_users_job(job_id): logger.debug('checking bigquery results for job {}'.format(job_id)) bq = get_bigquery_client() complete, row_count = bq.check_job(job_id) if complete: logger.info('importing active user records, {} rows'.format(row_count)) results = bq.get_query_rows(job_id) with wigo_db.transaction(commit_on_select=False): for record in results: user_id = record['user_id'] last_active = record['last_active'] wigo_db.get_redis(True).hset(skey('user', user_id, 'meta'), 'last_active', last_active) logger.info('finished importing active user records') else: scheduler.schedule(datetime.utcnow() + timedelta(seconds=5), check_friend_interactions_job, args=[job_id], result_ttl=0, timeout=30)
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()
def update_top_friends(user_id, interaction_scores): last_active_window = datetime.utcnow() - timedelta(days=30) friend_ids = wigo_db.sorted_set_rrange(skey('user', user_id, 'friends')) friends = User.find(friend_ids) # remove missing friends with wigo_db.transaction(commit_on_select=False): for index, f in enumerate(friends): if f is None: friend_id = friend_ids[index] if not wigo_db.exists(skey('user', friend_id)): wigo_db.sorted_set_remove(skey('user', user_id, 'friends'), friend_id) wigo_db.set_remove( skey('user', user_id, 'friends', 'private'), friend_id) for type in [ 'top', 'alpha', 'friend_requests', 'friend_requested' ]: wigo_db.sorted_set_remove( skey('user', user_id, 'friends', type), friend_id) # remove nulls friends = [f for f in friends if f is not None] # get all my friends last active dates p = wigo_db.redis.pipeline() for index, f in enumerate(friends): p.hget(skey(f, 'meta'), 'last_active') last_active_dates = p.execute() for index, f in enumerate(friends): last_active = last_active_dates[index] last_active = datetime.utcfromtimestamp( float(last_active)) if last_active else last_active_window f.last_active = last_active # bucket the friends buckets = [[], [], [], [], []] for f in friends: score = interaction_scores.get(f.id, 0) if score == 0: buckets[0].append(f) elif score <= 3: buckets[1].append(f) elif score <= 10: buckets[2].append(f) elif score <= 20: buckets[3].append(f) else: buckets[4].append(f) # score def get_score(f): score = 1 if f.gender == 'female': score += 2 if f.last_active > last_active_window: score += 2 return score for b in buckets: b.sort(key=lambda f: random() * get_score(f)) top_friends_key = skey('user', user_id, 'friends', 'top') with wigo_db.transaction(commit_on_select=False): score = 0 for b in buckets: for f in b: wigo_db.sorted_set_add(top_friends_key, f.id, score) score += 1
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'))
def clean_old_events(): with wigo_db.transaction(commit_on_select=False): for group in get_all_groups(): wigo_db.clean_old(skey(group, 'events'), Event.TTL) wigo_db.clean_old(skey('global', 'events'), Event.TTL)
def event_related_change(group_id, event_id, is_global=False, deleted=False): from server.db import redis lock = redis.lock('locks:group_event_change:{}:{}'.format( group_id, event_id), timeout=120) if lock.acquire(blocking=False): try: agent.add_custom_parameter('group_id', group_id) logger.debug('recording event change in group {}'.format(group_id)) if not deleted: try: event = Event.find(event_id) event.deleted = False except DoesNotExist: event = Event({'id': event_id, 'group_id': group_id}) event.deleted = True else: event = Event({'id': event_id, 'group_id': group_id}) event.deleted = True group = Group.find(group_id) with wigo_db.transaction(commit_on_select=False): # add to the time in case other changes come in while this lock is taken, # or in case the job queues get backed up group.track_meta('last_event_change', time() + EVENT_CHANGE_TIME_BUFFER) if is_global or event.is_global: groups_to_add_to = get_all_groups() else: radius = 100 population = group.population or 50000 if population < 60000: radius = 40 elif population < 100000: radius = 60 groups_to_add_to = get_close_groups( group.latitude, group.longitude, radius) num_visited = 0 for group_to_add_to in groups_to_add_to: if group_to_add_to.id == group.id: continue # index this event into the close group if event.deleted is False: event.update_global_events(group=group_to_add_to) else: event.remove_index(group=group_to_add_to) # track the change for the group group_to_add_to.track_meta( 'last_event_change', time() + EVENT_CHANGE_TIME_BUFFER) num_visited += 1 if (num_visited % 25) == 0: lock.extend(30) finally: lock.release()