def create_user_if_not_exists(profile): try: chat_driver = get_driver() current_chat_user = chat_driver.users.get_user_by_username( profile.handle) profile.chat_id = current_chat_user['id'] profile.save() return False, current_chat_user except ResourceNotFound as RNF: new_user_request = create_user.apply_async( args=[{ "email": profile.user.email, "username": profile.handle, "first_name": profile.user.first_name, "last_name": profile.user.last_name, "nickname": profile.handle, "auth_data": f'{profile.user.id}', "auth_service": "gitcoin", "locale": "en", "props": {}, "notify_props": { "email": "false", "push": "mention", "desktop": "all", "desktop_sound": "true", "mention_keys": f'{profile.handle}, @{profile.handle}', "channel": "true", "first_name": "false" }, }, { "tid": settings.GITCOIN_HACK_CHAT_TEAM_ID }]) return True, new_user_request.get()
def chat_presence(request): """Sets user presence on mattermost.""" if not request.user.is_authenticated: return JsonResponse({'status': 'OK'}) profile = request.user.profile if not profile.chat_id: return JsonResponse({'status': 'OK'}) # setup driver driver = get_driver() # determine current status/ should we set the user as online in mm? current_status = driver.client.post('/users/status/ids', [profile.chat_id]) manual = current_status[0]['manual'] current_status = current_status[0]['status'] set_status = current_status == 'offline' or manual or settings.DEBUG # if so, make it so if set_status: new_status = 'online' if current_status in ['away', 'dnd']: new_status = current_status driver.client.put(f'/users/{profile.chat_id}/status', { 'user_id': profile.chat_id, 'status': new_status }) # set a marker of when this user was last seen.. # so that get_user_prsence can clean it up later redis = RedisService().redis redis.set(profile.chat_id, timezone.now().timestamp()) redis.set(f"chat:{profile.chat_id}", new_status) return JsonResponse({'status': 'OK'})
def chat_users(): from chat.tasks import get_driver try: chat_driver = get_driver() stats_request = chat_driver.users.get_stats() Stat.objects.create( key='chat_total_users', val=stats_request['total_users_count'], ) hack_team_stats = chat_driver.teams.get_team_stats( settings.GITCOIN_HACK_CHAT_TEAM_ID ) core_team_stats = chat_driver.teams.get_team_stats( settings.GITCOIN_CHAT_TEAM_ID ) active_user_count = hack_team_stats['active_member_count'] + core_team_stats['active_member_count'] Stat.objects.create( key='chat_active_users', val=active_user_count, ) except Exception as e: logging.info(str(e))
def chat_users(): from chat.tasks import get_driver chat_driver = get_driver() stats_request = chat_driver.users.stats() if 'message' not in stats_request: Stat.objects.create( key='total_users', val=stats_request['total_users_count'], )
def chat_users(): from chat.tasks import get_driver try: chat_driver = get_driver() stats_request = chat_driver.system.get_analytics({ 'name': 'standard', 'team_id': '' }) stats_request = {ele['name']: ele["value"] for ele in stats_request} Stat.objects.create( key='chat_total_users', val=stats_request['unique_user_count'], ) Stat.objects.create( key='chat_daily_active_users', val=stats_request['daily_active_users'], ) Stat.objects.create( key='chat_monthly_active_users', val=stats_request['monthly_active_users'], ) Stat.objects.create( key='chat_total_post_counts', val=stats_request['post_count'], ) Stat.objects.create( key='chat_total_public_channels', val=stats_request['channel_open_count'], ) Stat.objects.create( key='chat_total_private_channels', val=stats_request['channel_private_count'], ) hack_team_stats = chat_driver.teams.get_team_stats( settings.GITCOIN_HACK_CHAT_TEAM_ID) core_team_stats = chat_driver.teams.get_team_stats( settings.GITCOIN_CHAT_TEAM_ID) active_user_count = hack_team_stats[ 'active_member_count'] + core_team_stats['active_member_count'] Stat.objects.create( key='chat_active_users', val=active_user_count, ) except Exception as e: logging.info(str(e))
def post_to_chat(channel, msg): try: from chat.tasks import get_driver chat_driver = get_driver() response = chat_driver.posts.create_post({ 'channel_id': channel, 'message': msg }) if 'message' in response: return False return False except Exception as e: print(e) return False
def chat(request): """Render chat landing page response.""" try: chat_driver = get_driver() chat_stats = chat_driver.teams.get_team_stats(settings.GITCOIN_CHAT_TEAM_ID) if 'message' not in chat_stats: users_online = chat_stats['active_member_count'] else: users_online = 'N/A' except Exception as e: users_online = 'N/A' context = { 'users_online': users_online } return TemplateResponse(request, 'chat.html', context)
def create_channel_if_not_exists(channel_opts): try: chat_driver = get_driver() channel_lookup_response = chat_driver.channels.get_channel_by_name( channel_opts['team_id'], channel_opts['channel_name']) return False, channel_lookup_response except ResourceNotFound as RNF: try: result = create_channel.apply_async(args=[channel_opts]) bounty_channel_id_response = result.get() if 'message' in bounty_channel_id_response: raise ValueError(bounty_channel_id_response['message']) return True, bounty_channel_id_response except Exception as e: logger.error(str(e))
def chat(request): """Render chat landing page response.""" try: chat_driver = get_driver() chat_stats = chat_driver.teams.get_team_stats( settings.GITCOIN_CHAT_TEAM_ID) if 'message' not in chat_stats: users_online = chat_stats['active_member_count'] else: users_online = 'N/A' except Exception as e: print(str(e)) users_online = 'N/A' context = { 'users_online': users_online, 'title': "Chat", 'cards_desc': f"Gitcoin chat has {users_online} users online now!" } return TemplateResponse(request, 'chat.html', context)
def handle(self, *args, **options): # connect to API d = get_driver() teams = d.teams.get_teams() # outer vars all_usernames = [] all_user_statuses = {} all_response = [] for team in teams: if team['display_name'] == 'Codefund': continue # pull back users on team print(team['display_name']) all_users = [] cont = True per_page = 60 page = 0 while cont: params = {'in_team':team['id'], 'sort':'last_activity_at', 'per_page': per_page, 'page': page} users = d.users.get_users(params=params) all_users += users cont = len(users) == per_page page += 1 #for testing on small amount of data #if settings.DEBUG: # cont = False for user in users: pass # get through all users print(f"- {len(all_users)}") users_status = d.client.post('/users/status/ids', [ele['id'] for ele in all_users]) all_response += users_status users_status_by_id = { ele['user_id']: ele for ele in users_status } all_usernames += [ele['username'].lower() for ele in all_users] # iterate through each one, and sync it to our DB for user in all_users: last_activity_at_1 = user['last_activity_at'] last_activity_at_2 = users_status_by_id[user['id']]['last_activity_at'] status = users_status_by_id[user['id']]['status'] last_activity_at = max(last_activity_at_2, last_activity_at_1) username = user['username'] timestamp = int(last_activity_at/1000) timestamp = timezone.datetime.utcfromtimestamp(timestamp).replace(tzinfo=pytz.utc) all_user_statuses[username] = (status, timestamp, user['id']) # look for manual statuses set by /api/v0.1/chat route and clean them up if needed redis = RedisService().redis for ele in all_response: user_id = ele['user_id'] status = ele['status'] if status == 'offline': continue # user has been offline for 10 mins # update mattermost, and redis max_delta = (10*60) # calc it now = timezone.now().timestamp() last_action_mattermost = int(ele['last_activity_at']/1000) redis_response = redis.get(user_id) last_seen_gc = int(float(redis_response)) if redis_response else now # do update is_away_mm = ((now - last_action_mattermost) > max_delta) is_away_gc = (now - last_seen_gc) > max_delta manual = ele['manual'] update_ele = (manual and is_away_gc) or (not manual and is_away_mm) if update_ele or settings.DEBUG: new_status = 'offline' d.client.put(f'/users/{user_id}/status', {'user_id': user_id, 'status': new_status}) redis.set(user_id, 0) # update all usernames profiles = Profile.objects.filter(handle__in=all_usernames) for profile in profiles: profile.last_chat_status, profile.last_chat_seen, profile.chat_id = all_user_statuses[profile.handle] bulk_update(profiles, update_fields=['last_chat_seen', 'last_chat_status', 'chat_id'])
def preprocess(request): """Handle inserting pertinent data into the current context.""" # make lbcheck super lightweight if request.path == '/lbcheck': return {} from marketing.utils import get_stat try: num_slack = int(get_stat('slack_users')) except Exception: num_slack = 0 if num_slack > 1000: num_slack = f'{str(round((num_slack) / 1000, 1))}k' user_is_authenticated = request.user.is_authenticated profile = request.user.profile if user_is_authenticated and hasattr( request.user, 'profile') else None email_subs = profile.email_subscriptions if profile else None email_key = email_subs.first( ).priv if user_is_authenticated and email_subs and email_subs.exists( ) else '' if user_is_authenticated and profile and profile.pk: # what actions to take? record_join = not profile.last_visit record_visit = not profile.last_visit or profile.last_visit < ( timezone.now() - timezone.timedelta(seconds=RECORD_VISIT_EVERY_N_SECONDS)) if record_visit: ip_address = get_ip(request) profile.last_visit = timezone.now() try: profile.as_dict = json.loads(json.dumps(profile.to_dict())) profile.save() except Exception as e: logger.exception(e) metadata = { 'useragent': request.META['HTTP_USER_AGENT'], 'referrer': request.META.get('HTTP_REFERER', None), 'path': request.META.get('PATH_INFO', None), } UserAction.objects.create( user=request.user, profile=profile, action='Visit', location_data=get_location_from_ip(ip_address), ip_address=ip_address, utm=_get_utm_from_cookie(request), metadata=metadata, ) if record_join: Activity.objects.create(profile=profile, activity_type='joined') # handles marketing callbacks if request.GET.get('cb'): callback = request.GET.get('cb') handle_marketing_callback(callback, request) chat_unread_messages = False if profile and profile.chat_id: try: from chat.tasks import get_driver chat_driver = get_driver() chat_unreads_request = chat_driver.teams.get_team_unreads_for_user( profile.chat_id) if 'message' not in chat_unreads_request: for teams in chat_unreads_request: if teams['msg_count'] > 0 or teams['mention_count'] > 0: chat_unread_messages = True break except Exception as e: logger.error(str(e)) context = { 'STATIC_URL': settings.STATIC_URL, 'MEDIA_URL': settings.MEDIA_URL, 'num_slack': num_slack, 'chat_unread_messages': chat_unread_messages, 'github_handle': request.user.username if user_is_authenticated else False, 'email': request.user.email if user_is_authenticated else False, 'name': request.user.get_full_name() if user_is_authenticated else False, 'raven_js_version': settings.RAVEN_JS_VERSION, 'raven_js_dsn': settings.SENTRY_JS_DSN, 'release': settings.RELEASE, 'env': settings.ENV, 'INFURA_V3_PROJECT_ID': settings.INFURA_V3_PROJECT_ID, 'email_key': email_key, 'orgs': profile.organizations if profile else [], 'profile_id': profile.id if profile else '', 'hotjar': settings.HOTJAR_CONFIG, 'ipfs_config': { 'host': settings.JS_IPFS_HOST, 'port': settings.IPFS_API_PORT, 'protocol': settings.IPFS_API_SCHEME, 'root': settings.IPFS_API_ROOT, }, 'access_token': profile.access_token if profile else '', 'is_staff': request.user.is_staff if user_is_authenticated else False, 'is_moderator': profile.is_moderator if profile else False, 'persona_is_funder': profile.persona_is_funder if profile else False, 'persona_is_hunter': profile.persona_is_hunter if profile else False, 'profile_url': profile.url if profile else False, 'quests_live': settings.QUESTS_LIVE, } context['json_context'] = json.dumps(context) if context['github_handle']: context['unclaimed_tips'] = Tip.objects.filter( expires_date__gte=timezone.now(), receive_txid='', username__iexact=context['github_handle'], web3_type='v3', ).send_happy_path() context['unclaimed_kudos'] = KudosTransfer.objects.filter( receive_txid='', username__iexact="@" + context['github_handle'], web3_type='v3', ).send_happy_path() if not settings.DEBUG: context['unclaimed_tips'] = context['unclaimed_tips'].filter( network='mainnet') context['unclaimed_kudos'] = context['unclaimed_kudos'].filter( network='mainnet') return context