def participation_ranks(round_name): """Generate the scoreboard for participation game.""" cache_key = "p_ranks-%s" % slugify(round_name) p_ranks = cache_mgr.get_cache(cache_key) if p_ranks is None: p_settings, _ = ParticipationSetting.objects.get_or_create(pk=1) p_ranks = { "participation_100": [], "participation_75": [], "participation_50": [], "participation_0": [], "p_settings": p_settings} team_participation = TeamParticipation.objects.filter( round_name=round_name).select_related("team") if not team_participation: team_participation = Team.objects.all() for p in team_participation: p.team = p p.participation = 0 p_ranks["participation_0"].append(p) else: for p in team_participation: if p.participation >= 100: p_ranks["participation_100"].append(p) elif p.participation >= 75: p_ranks["participation_75"].append(p) elif p.participation >= 50: p_ranks["participation_50"].append(p) else: p_ranks["participation_0"].append(p) # less than 50 cache_mgr.set_cache(cache_key, p_ranks, 3600) return p_ranks
def get_all_round_info_from_cache(): """Returns a dictionary containing all the round information. example: {"rounds": {"Round 1": {"start": start_date, "end": end_date,},}, "competition_start": start_date, "competition_end": end_date} """ rounds_info = cache_mgr.get_cache('rounds') if rounds_info is None: roundsettings = RoundSetting.objects.all() if not roundsettings: RoundSetting.objects.create() roundsettings = RoundSetting.objects.all() rounds_info = {} rounds = {} index = 0 # roundsettings is ordered by "start" r = None for r in roundsettings: rounds[r.name] = { "start": r.start, "end": r.end, "round_reset": r.round_reset, "display_scoreboard": r.display_scoreboard} if index == 0: rounds_info["competition_start"] = r.start index += 1 rounds_info["competition_end"] = r.end rounds_info["rounds"] = rounds cache_mgr.set_cache('rounds', rounds_info, 2592000) return rounds_info
def score_setting(): """returns the score settings.""" score = cache_mgr.get_cache('score_setting') if not score: score, _ = ScoreSetting.objects.get_or_create(pk=1) cache_mgr.set_cache('score_setting', score, 2592000) return score
def get_unread_notifications(user, limit=None): """Retrieves the user's unread notifications that are to be displayed on the web. Returns a dictionary containing their alerts, their unread notifications, and if there are more unread notifications.""" if not user: return None notifications = cache_mgr.get_cache("notification-%s" % user.username) if notifications is None: notifications = { "has_more": False, "use_facebook": settings.MAKAHIKI_USE_FACEBOOK } # Find undisplayed alert notifications. notifications.update({"alerts": get_user_alert_notifications(user)}) # Get unread notifications unread_notifications = user.usernotification_set.filter( unread=True, ).order_by("-level", "-created_at") if limit: if unread_notifications.count() > limit: notifications.update({"has_more": True}) unread_notifications = unread_notifications[:limit] for item in unread_notifications: item.fb_contents = _strip_html_tag(item.contents) notifications.update({"unread": unread_notifications}) cache_mgr.set_cache("notification-%s" % user.username, notifications, 1800) return notifications
def get_unread_notifications(user, limit=None): """Retrieves the user's unread notifications that are to be displayed on the web. Returns a dictionary containing their alerts, their unread notifications, and if there are more unread notifications.""" if not user: return None notifications = cache_mgr.get_cache("notification-%s" % user.username) if notifications is None: notifications = {"has_more": False} # Find undisplayed alert notifications. notifications.update({"alerts": get_user_alert_notifications(user)}) # Get unread notifications unread_notifications = user.usernotification_set.filter(unread=True).order_by("-level", "-created_at") if limit: if unread_notifications.count() > limit: notifications.update({"has_more": True}) unread_notifications = unread_notifications[:limit] for item in unread_notifications: item.fb_contents = _strip_html_tag(item.contents) notifications.update({"unread": unread_notifications}) cache_mgr.set_cache("notification-%s" % user.username, notifications, 1800) return notifications
def get_available_golow_actions(user, related_resource): """Retrieves only the golow activities that a user can participate in.""" golow_actions = cache_mgr.get_cache('golow_actions-%s' % user.username) if golow_actions is None: actions = Action.objects.exclude(actionmember__user=user, ).filter( Q(expire_date__isnull=True) | Q(expire_date__gte=datetime.date.today()), related_resource=related_resource, pub_date__lte=datetime.date.today(), ).order_by("type", "priority") # pick one activity per type, until reach NUM_GOLOW_ACTIONS action_type = None golow_actions = [] for action in actions: if action_type == action.type: continue if is_unlock(user, action) and is_level_unlock(user, action.level): golow_actions.append(action) action_type = action.type if len(golow_actions) == NUM_GOLOW_ACTIONS: break cache_mgr.set_cache('golow_actions-%s' % user.username, golow_actions, 1800) return golow_actions
def resource_ranks(name, round_name=None): """Return the ranking of resource use for all teams.""" cache_key = "%s_ranks-%s" % (name, slugify(round_name)) ranks = cache_mgr.get_cache(cache_key) if ranks is None: resource_usage = _get_resource_usage(name) resource_setting = get_resource_setting(name) if resource_setting.winning_order == "Ascending": ordering = "total" else: ordering = "-total" round_info = challenge_mgr.get_round_info(round_name) if not round_info: return None usage_ranks = resource_usage.objects.filter( date__lte=round_info["end"].date).values("team__name").annotate( total=Sum("usage")).order_by(ordering) ranks = [] for rank in usage_ranks: ranks.append(rank) cache_mgr.set_cache(cache_key, ranks, 3600) return ranks
def group_active_participation(num_results=None, round_name=None): """Calculate active participation.""" if not round_name: round_name = challenge_mgr.get_round_name() participation = cache_mgr.get_cache('group_active_p-%s' % slugify(round_name)) if participation is None: active_participation = Group.objects.filter( team__profile__scoreboardentry__points__gte=score_mgr.active_threshold_points(), team__profile__scoreboardentry__round_name=round_name).annotate( user_count=Count('team__profile')).order_by('-user_count') if num_results: active_participation = active_participation[:num_results] participation = [] for g in active_participation: group_size = 0 for t in g.team_set.all(): group_size += t.profile_set.count() g.active_participation = (g.user_count * 100) / group_size participation.append(g) for g in Group.objects.all(): if len(participation) == num_results: break if not g in active_participation: g.active_participation = 0 participation.append(g) cache_mgr.set_cache('group_active_p-%s' % slugify(round_name), participation, 1800) return participation
def referral_setting(): """returns the referral settings.""" referral = cache_mgr.get_cache('referral_setting') if not referral: referral, _ = ReferralSetting.objects.get_or_create(pk=1) cache_mgr.set_cache('referral_setting', referral, 2592000) return referral
def get_all_enabled_widgets(): """Returns the enabled widgets for each page, taking into account of the PageSetting and GameSetting.""" page_widgets = cache_mgr.get_cache("enabled_widgets") if page_widgets is None: page_setting = PageSetting.objects.filter( enabled=True).select_related("page") page_widgets = {} for ps in page_setting: name = ps.page.name if not name in page_widgets: page_widgets[name] = [] widgets = page_widgets[name] # check if the game this widget belongs to is enabled in the game info game_enabled = False gss = GameSetting.objects.filter( widget=ps.widget).select_related("game") for gs in gss: if gs.game.enabled: game_enabled = True break if not gss or game_enabled: widgets.append(ps) cache_mgr.set_cache("enabled_widgets", page_widgets, 2592000) return page_widgets
def resource_goal_ranks(resource, round_name=None): """Generate the scoreboard for resource goals.""" cache_key = "%s_goal_ranks-%s" % (resource, slugify(round_name)) goal_ranks = cache_mgr.get_cache(cache_key) if goal_ranks is None: goal_ranks = [] goal = _get_resource_goal(resource) round_info = challenge_mgr.get_round_info(round_name) if not round_info: return None ranks = goal.objects.filter( goal_status="Below the goal", date__lte=round_info["end"].date).values("team__name").annotate( completions=Count("team"), average_reduction=Avg("percent_reduction")).order_by( "-completions", "-average_reduction") for rank in ranks: goal_ranks.append(rank) total_count = Team.objects.count() if len(goal_ranks) != total_count: for t in Team.objects.all(): if not t.name in goal_ranks: rank = {"team__name": t.name, "completions": 0, "average_reduction": 0} goal_ranks.append(rank) if len(goal_ranks) == total_count: break cache_mgr.set_cache(cache_key, goal_ranks, 3600 * 24) return goal_ranks
def get_resource_setting(name): """Returns the resource settings for the specified name.""" resource_setting = cache_mgr.get_cache("resource_setting-%s" % name) if resource_setting is None: resource_setting = ResourceSetting.objects.get(name=name) cache_mgr.set_cache("resource_setting-%s" % name, resource_setting, 2592000) return resource_setting
def participation_ranks(round_name): """Generate the scoreboard for participation game.""" cache_key = "p_ranks-%s" % slugify(round_name) p_ranks = cache_mgr.get_cache(cache_key) if p_ranks is None: p_settings, _ = ParticipationSetting.objects.get_or_create(pk=1) p_ranks = { "participation_100": [], "participation_75": [], "participation_50": [], "participation_0": [], "p_settings": p_settings } team_participation = TeamParticipation.objects.filter( round_name=round_name).select_related("team") if not team_participation: team_participation = Team.objects.all() for p in team_participation: p.team = p p.participation = 0 p_ranks["participation_0"].append(p) else: for p in team_participation: if p.participation >= 100: p_ranks["participation_100"].append(p) elif p.participation >= 75: p_ranks["participation_75"].append(p) elif p.participation >= 50: p_ranks["participation_50"].append(p) else: p_ranks["participation_0"].append(p) # less than 50 cache_mgr.set_cache(cache_key, p_ranks, 3600) return p_ranks
def group_resource_ranks(name, round_name=None): """Return the ranking of resource use for all teams.""" cache_key = "group_%s_ranks-%s" % (name, slugify(round_name)) ranks = cache_mgr.get_cache(cache_key) if ranks is None: resource_usage = _get_resource_usage(name) resource_setting = get_resource_setting(name) rate = resource_setting.conversion_rate if resource_setting.winning_order == "Ascending": ordering = "total" else: ordering = "-total" start_end = challenge_mgr.get_round_start_end(round_name) if start_end is not None: start, end = start_end else: return None usage_ranks = resource_usage.objects.filter( date__lte=end, date__gte=start).values("team__group__name").annotate( total=Sum("usage")).order_by(ordering) ranks = [] for rank in usage_ranks: ranks.append({"team__group__name": rank["team__group__name"], "total": utils.format_usage(rank["total"], rate)}) cache_mgr.set_cache(cache_key, ranks, 600) return ranks
def get_available_events(user): """Retrieves only the events that a user can participate in.""" events = cache_mgr.get_cache('user_events-%s' % user.username) if events is None: events = Event.objects.filter( Q(expire_date__isnull=True) | Q(expire_date__gte=datetime.date.today()), pub_date__lte=datetime.date.today(), event_date__gte=datetime.date.today(), ).order_by("event_date") unlock_events = [] for event in events: unlock = is_unlock(user, event) and not event.is_event_completed() if unlock: for loc in Grid.objects.filter(action=event): unlock = unlock and is_level_unlock(user, loc.level) if unlock: unlock_events.append(event) events = unlock_events # Cache the user_event cache_mgr.set_cache('user_events-%s' % user.username, events, 1800) return events
def get_available_golow_actions(user, related_resource): """Retrieves only the golow activities that a user can participate in.""" golow_actions = cache_mgr.get_cache('golow_actions-%s' % user.username) if golow_actions is None: actions = Action.objects.exclude( actionmember__user=user, ).filter( Q(expire_date__isnull=True) | Q(expire_date__gte=datetime.date.today()), related_resource=related_resource, pub_date__lte=datetime.date.today(), ).order_by("type", "name") # pick one activity per type, until reach NUM_GOLOW_ACTIONS action_type = None golow_actions = [] for action in actions: if action_type == action.type: continue unlock = is_unlock(user, action) if unlock: for loc in Grid.objects.filter(action=action): unlock = unlock and is_level_unlock(user, loc.level) if unlock: golow_actions.append(action) action_type = action.type if len(golow_actions) == NUM_GOLOW_ACTIONS: break cache_mgr.set_cache('golow_actions-%s' % user.username, golow_actions, 1800) return golow_actions
def get_all_enabled_widgets(): """Returns the enabled widgets for each page, taking into account of the PageSetting and GameSetting.""" page_widgets = cache_mgr.get_cache("enabled_widgets") if page_widgets is None: page_setting = PageSetting.objects.filter(enabled=True).select_related("page") page_widgets = {} for ps in page_setting: name = ps.page.name if not name in page_widgets: page_widgets[name] = [] widgets = page_widgets[name] # check if the game this widget belongs to is enabled in the game info game_enabled = False gss = GameSetting.objects.filter(widget=ps.widget).select_related("game") for gs in gss: if gs.game.enabled: game_enabled = True break if not gss or game_enabled: widgets.append(ps) cache_mgr.set_cache("enabled_widgets", page_widgets, 2592000) return page_widgets
def get_all_round_info_from_cache(): """Returns a dictionary containing all the round information. example: {"rounds": {"Round 1": {"start": start_date, "end": end_date,},}, "competition_start": start_date, "competition_end": end_date} """ rounds_info = cache_mgr.get_cache('rounds') if rounds_info is None: roundsettings = RoundSetting.objects.all() if not roundsettings: RoundSetting.objects.create() roundsettings = RoundSetting.objects.all() rounds_info = {} rounds = {} index = 0 # roundsettings is ordered by "start" r = None for r in roundsettings: rounds[r.name] = { "start": r.start, "end": r.end, "round_reset": r.round_reset, "display_scoreboard": r.display_scoreboard } if index == 0: rounds_info["competition_start"] = r.start index += 1 rounds_info["competition_end"] = r.end rounds_info["rounds"] = rounds cache_mgr.set_cache('rounds', rounds_info, 2592000) return rounds_info
def get_participations(): """returns the team participation in categories.""" return_dict = cache_mgr.get_cache("team_participation") if return_dict is None: p_settings, _ = ParticipationSetting.objects.get_or_create(pk=1) return_dict = { "participation_100": [], "participation_75": [], "participation_50": [], "participation_0": [], "p_settings": p_settings} team_participation = TeamParticipation.objects.all() if not team_participation: team_participation = Team.objects.all() for p in team_participation: p.team = p p.participation = 0 return_dict["participation_0"].append(p) else: for p in team_participation: if p.participation >= 100: return_dict["participation_100"].append(p) elif p.participation >= 75: return_dict["participation_75"].append(p) elif p.participation >= 50: return_dict["participation_50"].append(p) else: return_dict["participation_0"].append(p) # less than 50 cache_mgr.set_cache("team_participation", return_dict, 3600) return return_dict
def team_active_participation(num_results=None, round_name=None): """Calculate active participation.""" if not round_name: round_name = challenge_mgr.get_round_name() participation = cache_mgr.get_cache('active_p-%s' % slugify(round_name)) if participation is None: active_participation = Team.objects.filter( profile__scoreboardentry__points__gte=score_mgr.active_threshold_points(), profile__scoreboardentry__round_name=round_name).annotate( user_count=Count('profile')).order_by('-user_count') if num_results: active_participation = active_participation[:num_results] participation = [] for t in active_participation: if t.size: t.active_participation = (t.user_count * 100) / t.size else: t.active_participation = (t.user_count * 100) / t.profile_set.count() participation.append(t) for t in Team.objects.all(): if len(participation) == num_results: break if not t in active_participation: t.active_participation = 0 participation.append(t) cache_mgr.set_cache('active_p-%s' % slugify(round_name), participation, 1800) return participation
def group_active_participation(num_results=None, round_name=None): """Calculate active participation.""" if not round_name: round_name = challenge_mgr.get_round_name() participation = cache_mgr.get_cache('group_active_p-%s' % slugify(round_name)) if participation is None: active_participation = Group.objects.filter( team__profile__scoreboardentry__points__gte=score_mgr. active_threshold_points(), team__profile__scoreboardentry__round_name=round_name).annotate( user_count=Count('team__profile')).order_by('-user_count') if num_results: active_participation = active_participation[:num_results] participation = [] for g in active_participation: group_size = 0 for t in g.team_set.all(): group_size += t.profile_set.count() g.active_participation = (g.user_count * 100) / group_size participation.append(g) for g in Group.objects.all(): if len(participation) == num_results: break if not g in active_participation: g.active_participation = 0 participation.append(g) cache_mgr.set_cache('group_active_p-%s' % slugify(round_name), participation, 1800) return participation
def team_active_participation(num_results=None, round_name=None): """Calculate active participation.""" if not round_name: round_name = challenge_mgr.get_round_name() participation = cache_mgr.get_cache('active_p-%s' % slugify(round_name)) if participation is None: active_participation = Team.objects.filter( profile__scoreboardentry__points__gte=score_mgr. active_threshold_points(), profile__scoreboardentry__round_name=round_name).annotate( user_count=Count('profile')).order_by('-user_count') if num_results: active_participation = active_participation[:num_results] participation = [] for t in active_participation: if t.size: t.active_participation = (t.user_count * 100) / t.size else: t.active_participation = (t.user_count * 100) / t.profile_set.count() participation.append(t) for t in Team.objects.all(): if len(participation) == num_results: break if not t in active_participation: t.active_participation = 0 participation.append(t) cache_mgr.set_cache('active_p-%s' % slugify(round_name), participation, 1800) return participation
def referral_setting(): """returns the referral settings.""" referral = cache_mgr.get_cache("referral_setting") if not referral: referral, _ = ReferralSetting.objects.get_or_create(pk=1) cache_mgr.set_cache("referral_setting", referral, 2592000) return referral
def resource_ranks(name, round_name=None): """Return the ranking of resource use for all teams.""" cache_key = "%s_ranks-%s" % (name, slugify(round_name)) ranks = cache_mgr.get_cache(cache_key) if ranks is None: resource_usage = _get_resource_usage(name) resource_setting = get_resource_setting(name) rate = resource_setting.conversion_rate if resource_setting.winning_order == "Ascending": ordering = "total" else: ordering = "-total" round_info = challenge_mgr.get_round_info(round_name) if not round_info: return None all_rounds_info = challenge_mgr.get_all_round_info() usage_ranks = resource_usage.objects.filter( date__lte=round_info["end"].date, date__gte=all_rounds_info["competition_start"]).values("team__name").annotate( total=Sum("usage")).order_by(ordering) ranks = [] for rank in usage_ranks: ranks.append({"team__name": rank["team__name"], "total": utils.format_usage(rank["total"], rate)}) cache_mgr.set_cache(cache_key, ranks, 600) return ranks
def group_resource_ranks(name, round_name=None): """Return the ranking of resource use for all teams.""" cache_key = "group_%s_ranks-%s" % (name, slugify(round_name)) ranks = cache_mgr.get_cache(cache_key) if ranks is None: resource_usage = _get_resource_usage(name) resource_setting = get_resource_setting(name) rate = resource_setting.conversion_rate if resource_setting.winning_order == "Ascending": ordering = "total" else: ordering = "-total" start, end = challenge_mgr.get_round_start_end(round_name) usage_ranks = resource_usage.objects.filter( date__lte=end, date__gte=start).values("team__group__name").annotate( total=Sum("usage")).order_by(ordering) ranks = [] for rank in usage_ranks: ranks.append({ "team__group__name": rank["team__group__name"], "total": utils.format_usage(rank["total"], rate) }) cache_mgr.set_cache(cache_key, ranks, 600) return ranks
def testCache(self): """Tests basic cache operations.""" self.assertTrue(cache_mgr.info() is not None, "Test that info() return something.") cache_mgr.set_cache('test_key', 'test_value') if settings.MAKAHIKI_USE_MEMCACHED: self.assertEqual(cache_mgr.get_cache('test_key'), 'test_value', "Test get the correct value from cache.") cache_mgr.delete('test_key') self.assertEqual(cache_mgr.get_cache('test_key'), None, "Test get the correct value from cache.") cache_mgr.clear() self.assertEqual(cache_mgr.get_cache('test_key'), None, "Test get the correct value from cache.")
def get_all_enabled_games(): """Returns the enabled games.""" games = cache_mgr.get_cache("enabled_games") if games is None: games = [] for game in GameInfo.objects.filter(enabled=True): games.append(game.name) cache_mgr.set_cache("enabled_games", games, 2592000) return games
def team_normalize_size(): """returns the normalize size for all the teams. It is the max team size across all teams.""" size = cache_mgr.get_cache('team_normalize_size') if size is None: size = Team.objects.all().aggregate(max=Max('size'))["max"] if not size: size = 0 cache_mgr.set_cache('team_normalize_size', size, 2592000) return size
def get_quests_from_cache(user): """ get the quests for the user and store in cache. """ return_dict = cache_mgr.get_cache("get_quests-%s" % user.username) if return_dict is None: return_dict = get_quests(user) cache_mgr.set_cache("get_quests-%s" % user.username, return_dict, 1800) return return_dict
def all_page_info(user): """Returns a list of all pages with their current lock state.""" all_pages = cache_mgr.get_cache("all_page_info-%s" % user.username) if not all_pages: all_pages = PageInfo.objects.exclude(name="home").order_by("priority") for page in all_pages: page.is_unlock = eval_page_unlock(user, page) cache_mgr.set_cache("all_page_info-%s" % user.username, all_pages, 1800) return all_pages
def get_hourly_goal_data(team, resource): """:return: the energy goal data for the user's team.""" hourly_goal = cache_mgr.get_cache("hgoal-%s-%d" % (resource, team.id)) if hourly_goal is None: date = datetime.datetime.today() hourly_goal = {"resource": resource} if resource_mgr.is_blackout(date): hourly_goal.update({"is_blackout": True}) else: resource_setting = resource_mgr.get_resource_setting(resource) unit = resource_setting.unit rate = resource_setting.conversion_rate usage_data = resource_mgr.team_resource_data(date=date.date(), team=team, resource=resource) if usage_data: actual_usage = utils.format_usage(usage_data.usage, rate) goal_settings = resource_goal.team_goal_settings( team, resource) goal_percent = resource_goal.get_goal_percent( date, team, resource, goal_settings) baseline = resource_goal.team_hourly_resource_baseline( resource, team, usage_data.date, usage_data.time) goal_usage = utils.format_usage( baseline * (100 - goal_percent) / 100, rate) warning_usage = utils.format_usage( baseline * (100 - goal_percent / 2) / 100, rate) actual_diff = abs(actual_usage - goal_usage) hourly_goal.update({ "goal_usage": goal_usage, "warning_usage": warning_usage, "actual_usage": actual_usage, "actual_diff": actual_diff, "updated_at": datetime.datetime.combine(date=usage_data.date, time=usage_data.time), "unit": unit, }) else: hourly_goal.update({"no_data": True}) cache_mgr.set_cache("hgoal-%s-%d" % (resource, team.id), hourly_goal, 600) return hourly_goal
def get_challenge(): """returns the ChallengeSetting object, from cache if cache is enabled""" challenge = cache_mgr.get_cache('challenge') if not challenge: challenge, _ = ChallengeSetting.objects.get_or_create(pk=1) # create the admin create_admin_user() cache_mgr.set_cache('challenge', challenge, 2592000) return challenge
def get_resource_setting(name): """Returns the resource settings for the specified name.""" resource_setting = cache_mgr.get_cache("resource_setting-%s" % name) if resource_setting is None: if ResourceSetting.objects.count() == 0: ResourceSetting.objects.create(name="energy", unit="kWh", winning_order="Ascending") ResourceSetting.objects.create(name="water", unit="Gallon", winning_order="Ascending") ResourceSetting.objects.create(name="waste", unit="Ton", winning_order="Descending") resource_setting = ResourceSetting.objects.get(name=name) cache_mgr.set_cache("resource_setting-%s" % name, resource_setting, 2592000) return resource_setting
def get_quests_from_cache(user): """ get the quests for the user and store in cache. """ if not challenge_mgr.is_game_enabled("Quest Game Mechanics"): return {} return_dict = cache_mgr.get_cache("get_quests-%s" % user.username) if return_dict is None: return_dict = get_quests(user) cache_mgr.set_cache("get_quests-%s" % user.username, return_dict, 1800) return return_dict
def resource_goal_ranks(resource, round_name=None): """Generate the scoreboard for resource goals.""" if not challenge_mgr.is_game_enabled("%s Game" % resource.capitalize()): return None cache_key = "%s_goal_ranks-%s" % (resource, slugify(round_name)) goal_ranks = cache_mgr.get_cache(cache_key) if goal_ranks is None: goal_ranks = [] goal = get_resource_goal(resource) start_end = challenge_mgr.get_round_start_end(round_name) if start_end is not None: start, end = start_end else: return None ranks = goal.objects.filter( goal_status="Below the goal", date__gte=start, date__lte=end).values("team__name").annotate( completions=Count("team"), average_reduction=Avg("percent_reduction")).order_by( "-completions", "-average_reduction") for rank in ranks: goal_ranks.append(rank) total_count = Team.objects.count() if len(goal_ranks) != total_count: for t in Team.objects.all(): # find the team in the goal_ranks count = 0 for goal_rank in goal_ranks: if t.name == goal_rank["team__name"]: break else: count += 1 if count == len(goal_ranks): # not found rank = { "team__name": t.name, "completions": 0, "average_reduction": 0 } goal_ranks.append(rank) if len(goal_ranks) == total_count: break cache_mgr.set_cache(cache_key, goal_ranks, 3600 * 24) return goal_ranks
def get_level_actions(user): """Return the level list with the action info in categories""" levels = cache_mgr.get_cache("smartgrid-levels-%s" % user.username) if levels is None: completed_actions = get_completed_actions(user) levels = [] for level in Level.objects.all(): level.is_unlock = utils.eval_predicates(level.unlock_condition, user) if level.is_unlock: level.is_complete = True categories = [] action_list = None category = None for action in level.action_set.all().select_related("category"): if action.slug in completed_actions: action.member = completed_actions[action.slug] action.is_unlock = True action.completed = True else: action.is_unlock = is_unlock(user, action) action.completed = False # if there is one action is not completed, set the level to in-completed if not action.completed: level.is_complete = False # the action are ordered by level and category if category != action.category: if category: # a new category category.task_list = action_list categories.append(category) action_list = [] category = action.category action_list.append(action) if category: # last category category.task_list = action_list categories.append(category) level.cat_list = categories levels.append(level) # Cache the categories for 30 minutes (or until they are invalidated) cache_mgr.set_cache("smartgrid-levels-%s" % user, levels, 1800) return levels
def team_goal_settings(team, resource): """Returns the goal settings for the given team and resource.""" if resource == "energy": goalsetting = EnergyGoalSetting elif resource == "water": goalsetting = WaterGoalSetting goalsettings = cache_mgr.get_cache("goal_setting-%s-%s" % (resource, team.name)) if goalsettings is None: goalsettings = goalsetting.objects.filter(team=team) if goalsettings: goalsettings = goalsettings[0] cache_mgr.set_cache("goal_setting-%s-%s" % (resource, team.name), goalsettings, 2592000) return goalsettings
def get_completed_actions(user): """returns the completed action for the user. It is stored as a dict of action slugs and its member status.""" actions = cache_mgr.get_cache("smartgrid-completed-%s" % user.username) if actions is None: actions = {} for member in ActionMember.objects.filter(user=user).select_related("action").order_by("-submission_date"): slug = member.action.slug if member.action.type != "commitment": actions[slug] = {"approval_status": member.approval_status} elif slug not in actions: actions[slug] = {"days_left": member.days_left(), "award_date": member.award_date} cache_mgr.set_cache("smartgrid-completed-%s" % user, actions, 1800) return actions
def is_unlock(user, action): """Returns the unlock status of the user action.""" levels = cache_mgr.get_cache('smartgrid-levels-%s' % user.username) if levels is None: # not cached, just check return eval_unlock(user, action) # cached format of levels is [[<Level>, [<ColumnGrid>*], # [<Grid>*], [active columns], max_column, max_row]+] for level in levels: for a in level[2]: if a.id == action.id: return a.is_unlock return False
def resource_goal_ranks(resource, round_name=None): """Generate the scoreboard for resource goals.""" if not challenge_mgr.is_game_enabled("%s Game" % resource.capitalize()): return None cache_key = "%s_goal_ranks-%s" % (resource, slugify(round_name)) goal_ranks = cache_mgr.get_cache(cache_key) if goal_ranks is None: goal_ranks = [] goal = get_resource_goal(resource) start_end = challenge_mgr.get_round_start_end(round_name) if start_end is not None: start, end = start_end else: return None ranks = goal.objects.filter( goal_status="Below the goal", date__gte=start, date__lte=end).values("team__name").annotate( completions=Count("team"), average_reduction=Avg("percent_reduction")).order_by( "-completions", "-average_reduction") for rank in ranks: goal_ranks.append(rank) total_count = Team.objects.count() if len(goal_ranks) != total_count: for t in Team.objects.all(): # find the team in the goal_ranks count = 0 for goal_rank in goal_ranks: if t.name == goal_rank["team__name"]: break else: count += 1 if count == len(goal_ranks): # not found rank = {"team__name": t.name, "completions": 0, "average_reduction": 0} goal_ranks.append(rank) if len(goal_ranks) == total_count: break cache_mgr.set_cache(cache_key, goal_ranks, 3600 * 24) return goal_ranks
def team_goal_settings(team, resource): """Returns the goal settings for the given team and resource.""" if resource == "energy": goalsetting = EnergyGoalSetting elif resource == "water": goalsetting = WaterGoalSetting cache_key = "goal_setting-%s-%s" % (resource, slugify(team.name)) goalsettings = cache_mgr.get_cache(cache_key) if goalsettings is None: goalsettings = goalsetting.objects.filter(team=team) if goalsettings: goalsettings = goalsettings[0] cache_mgr.set_cache(cache_key, goalsettings, 2592000) return goalsettings
def is_unlock(user, action): """Returns the unlock status of the user action.""" levels = cache_mgr.get_cache('smartgrid-levels-%s' % user.username) if levels is None: return eval_unlock(user, action) for level in levels: if hasattr(level, "cat_list"): for cat in level.cat_list: if cat.id == action.category_id: for t in cat.task_list: if t.id == action.id: return t.is_unlock return False
def is_unlock(user, action): """Returns the unlock status of the user action.""" levels = cache_mgr.get_cache("smartgrid-levels-%s" % user.username) if levels is None: return eval_unlock(user, action) for level in levels: if hasattr(level, "cat_list"): for cat in level.cat_list: if cat.id == action.category_id: for t in cat.task_list: if t.id == action.id: return t.is_unlock return False
def get_challenge(): """returns the ChallengeSetting object, from cache if cache is enabled""" challenge = cache_mgr.get_cache('challenge') if not challenge: challenge, _ = ChallengeSetting.objects.get_or_create(pk=1) # check the WattDepot URL to ensure it does't end with '/' if challenge.wattdepot_server_url: while challenge.wattdepot_server_url.endswith('/'): challenge.wattdepot_server_url = challenge.wattdepot_server_url[:-1] # create the admin create_admin_user() cache_mgr.set_cache('challenge', challenge, 2592000) return challenge
def get_submitted_actions(user): """returns the completed action for the user. It is stored as a dict of action slugs and its member status.""" actions = cache_mgr.get_cache('smartgrid-completed-%s' % user.username) if actions is None: actions = {} for member in ActionMember.objects.filter(user=user).select_related( "action").order_by("-submission_date"): slug = member.action.slug if member.action.type != "commitment": actions[slug] = { "approval_status": member.approval_status, } elif slug not in actions: actions[slug] = { "days_left": member.days_left(), "award_date": member.award_date, } cache_mgr.set_cache('smartgrid-completed-%s' % user, actions, 1800) return actions
def get_level_actions(user): """Return the level list with the action info in categories""" levels = cache_mgr.get_cache('smartgrid-levels-%s' % user.username) if levels is None: completed_actions = get_completed_actions(user) levels = [] for level in Level.objects.all(): level.is_unlock = utils.eval_predicates(level.unlock_condition, user) if level.is_unlock: if level.unlock_condition != "True": contents = "%s is unlocked." % level obj, created = UserNotification.objects.\ get_or_create(recipient=user, contents=contents, level=UserNotification.LEVEL_CHOICES[2][0]) if created: # only show the notification if it is new obj.display_alert = True obj.save() level.is_complete = True categories = [] action_list = None category = None for action in level.action_set.all().select_related( "category"): if action.slug in completed_actions: action.member = completed_actions[action.slug] action.is_unlock = True action.completed = True else: action.is_unlock = is_unlock(user, action) action.completed = False action.availablity = availablity(action) # if there is one action is not completed, set the level to in-completed if not action.completed: level.is_complete = False # the action are ordered by level and category if category != action.category: if category: # a new category category.task_list = action_list categories.append(category) action_list = [] category = action.category action_list.append(action) if category: # last category category.task_list = action_list categories.append(category) level.cat_list = categories levels.append(level) # Cache the categories for 30 minutes (or until they are invalidated) cache_mgr.set_cache('smartgrid-levels-%s' % user, levels, 1800) return levels
def get_level_actions(user): # pylint: disable=R0914,R0912,R0915 """Returns the smart grid as defined in the Smart Grid Designer. The grid is a list of lists with the format [<Level>, [<ColumnGrid>*], [<Grid>*], [active columns], max_column, max_row]""" levels = cache_mgr.get_cache('smartgrid-levels-%s' % user.username) if levels is None: submitted_actions = get_submitted_actions(user) levels = [] for level in Level.objects.all(): level.is_unlock = predicate_mgr.eval_predicates( level.unlock_condition, user) if level.is_unlock: # only include unlocked levels if level.unlock_condition != "True": contents = "%s is unlocked." % level obj, created = UserNotification.objects.\ get_or_create(recipient=user, contents=contents, level=UserNotification.LEVEL_CHOICES[2][0]) if created: # only show the notification if it is new obj.display_alert = True obj.save() level_ret = [] level.is_complete = True level_ret.append(level) level_ret.append(ColumnGrid.objects.filter(level=level)) # level_ret.append(Grid.objects.filter(level=level)) max_column = len(ColumnGrid.objects.filter(level=level)) max_row = 0 just_actions = [] # update each action for row in Grid.objects.filter(level=level): action = Action.objects.get(slug=row.action.slug) action.row = row.row if row.row > max_row: max_row = row.row action.column = row.column if row.column > max_column: max_column = row.column if action.slug in submitted_actions: action.member = submitted_actions[action.slug] action.is_unlock = True action.completed = True else: action.is_unlock = is_unlock(user, action) action.completed = False action.availablity = availablity(action) # if there is one action is not completed, set the level to in-completed if not action.completed: level.is_complete = False just_actions.append(action) level_ret.append(just_actions) columns = [] for cat in level_ret[1]: if cat.column not in columns: columns.append(cat.column) for act in level_ret[2]: if act.column not in columns: columns.append(act.column) level_ret.append(columns) level_ret.append(max_column) level_ret.append(max_row) levels.append(level_ret) else: level_ret = [] level_ret.append(level) level_ret.append([]) level_ret.append([]) level_ret.append([]) level_ret.append(0) level_ret.append(0) levels.append(level_ret) # Cache the levels for 30 minutes (or until they are invalidated) cache_mgr.set_cache('smartgrid-levels-%s' % user, levels, 1800) return levels # pylint: enable=R0914,R0912,R0915