def get_context_data(self, **kwargs): dashboard_data = { 'summons_performed': { 'type': 'occurrences', 'total': self.get_log_count(), 'data': transform_to_dict( list(self.get_queryset().values('item__name').annotate( count=Count('pk')).order_by('-count')), name_key='item__name', ), } } item_list = GameItem.objects.filter( pk__in=set(self.get_queryset().values_list('item', flat=True))) context = { 'dashboard': dashboard_data, 'item_list': item_list, } context.update(kwargs) return super().get_context_data(**context)
def get_context_data(self, **kwargs): all_drops = get_drop_querysets(self.get_queryset()) recent_drops = { 'items': all_drops['items'].values( 'item', name=F('item__name'), icon=F('item__icon'), ).annotate(count=Sum('quantity')).order_by('-count') if 'items' in all_drops else [], 'monsters': replace_value_with_choice( list(all_drops['monsters'].values( name=F('monster__name'), icon=F('monster__image_filename'), element=F('monster__element'), stars=F('grade'), is_awakened=F('monster__is_awakened'), can_awaken=F('monster__can_awaken'), ).annotate(count=Count('pk')).order_by('-count')), {'element': Monster.ELEMENT_CHOICES}) if 'monsters' in all_drops else [], 'runes': replace_value_with_choice( list(all_drops['runes'].values( 'type', 'quality', 'stars', ).annotate(count=Count('pk')).order_by('-count') if 'runes' in all_drops else []), { 'type': RuneInstance.TYPE_CHOICES, 'quality': RuneInstance.QUALITY_CHOICES, }), } dashboard_data = { 'energy_spent': { 'type': 'occurrences', 'total': self.get_log_count(), 'data': transform_to_dict( list(self.get_queryset( ).values('level__dungeon__name').annotate( count=Sum('level__energy_cost'), ).order_by('-count')), name_key='level__dungeon__name', ), }, 'recent_drops': recent_drops, } level_list = Level.objects.filter( pk__in=set(self.get_queryset().values_list('level', flat=True))) kwargs['dashboard'] = dashboard_data kwargs['level_list'] = level_list return super().get_context_data(**kwargs)
def _rune_craft_report_data(qs, total_log_count, **kwargs): if qs.count() == 0: return None min_count = kwargs.get('min_count', max(1, int(MINIMUM_THRESHOLD * total_log_count))) return { 'type': { 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.values('type').annotate(count=Count('pk')).filter( count__gt=min_count).order_by('-count')), {'type': qs.model.CRAFT_CHOICES})), }, 'rune': { 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.values('rune').annotate(count=Count('pk')).filter( count__gt=min_count).order_by('-count')), {'rune': qs.model.TYPE_CHOICES})), }, 'quality': { 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.values('quality').annotate( count=Count('pk')).filter( count__gt=min_count).order_by('-count')), {'quality': qs.model.QUALITY_CHOICES})), }, 'stat': { 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.values('stat').annotate(count=Count('stat')).filter( count__gt=min_count).order_by('stat')), {'stat': qs.model.STAT_CHOICES})) }, }
def get_artifact_report(qs, total_log_count, **kwargs): if qs.count() == 0: return None min_count = kwargs.get('min_count', max(1, int(MINIMUM_THRESHOLD * total_log_count))) # Secondary effect distribution # Unable to use database aggregation on an ArrayField without ORM gymnastics, so post-process data in python all_effects = qs.annotate( flat_effects=Func(F('effects'), function='unnest')).values_list( 'flat_effects', flat=True) effect_counts = Counter(all_effects) return { 'element': { 'type': 'occurrences', 'total': qs.filter(slot=Artifact.SLOT_ELEMENTAL).count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.filter(slot=Artifact.SLOT_ELEMENTAL).values( 'element').annotate(count=Count('pk')).filter( count__gt=min_count).order_by('-count')), {'element': qs.model.ELEMENT_CHOICES})), }, 'archetype': { 'type': 'occurrences', 'total': qs.filter(slot=Artifact.SLOT_ARCHETYPE).count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.filter(slot=Artifact.SLOT_ARCHETYPE).values( 'archetype').annotate(count=Count('pk')).filter( count__gt=min_count).order_by('-count')), {'archetype': qs.model.ARCHETYPE_CHOICES})), }, 'quality': { 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.values('quality').annotate( count=Count('pk')).filter( count__gt=min_count).order_by('-count')), {'quality': qs.model.QUALITY_CHOICES})), }, 'main_stat': { 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.values('main_stat').annotate( count=Count('main_stat')).filter( count__gt=min_count).order_by('main_stat')), {'main_stat': qs.model.STAT_CHOICES})) }, 'effects': { 'type': 'occurrences', 'total': len(all_effects), 'data': transform_to_dict( replace_value_with_choice( sorted([{ 'effect': k, 'count': v } for k, v in effect_counts.items()], key=lambda count: count['effect']), {'effect': qs.model.EFFECT_CHOICES}), ) }, 'max_efficiency': { 'type': 'histogram', 'width': 5, 'data': histogram(qs, 'max_efficiency', range(0, 100, 5), slice_on='quality'), }, }
def get_rune_report(qs, total_log_count, **kwargs): if qs.count() == 0: return None min_count = kwargs.get('min_count', max(1, int(MINIMUM_THRESHOLD * total_log_count))) # Substat distribution # Unable to use database aggregation on an ArrayField without ORM gymnastics, so post-process data in python all_substats = qs.annotate( flat_substats=Func(F('substats'), function='unnest')).values_list( 'flat_substats', flat=True) substat_counts = Counter(all_substats) # Sell value ranges min_value, max_value = qs.aggregate(Min('value'), Max('value')).values() min_value = int(floor_to_nearest(min_value, 1000)) max_value = int(ceil_to_nearest(max_value, 1000)) return { 'stars': { 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( list( qs.values(grade=Concat(Cast('stars', CharField( )), Value('⭐'))).annotate(count=Count('pk')).filter( count__gt=min_count).order_by('-count'))), }, 'type': { 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.values('type').annotate(count=Count('pk')).filter( count__gt=min_count).order_by('-count')), {'type': qs.model.TYPE_CHOICES})), }, 'quality': { 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.values('quality').annotate( count=Count('pk')).filter( count__gt=min_count).order_by('-count')), {'quality': qs.model.QUALITY_CHOICES})), }, 'slot': { 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( list( qs.values('slot').annotate(count=Count('pk')).filter( count__gt=min_count).order_by('-count'))), }, 'main_stat': { 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.values('main_stat').annotate( count=Count('main_stat')).filter( count__gt=min_count).order_by('main_stat')), {'main_stat': qs.model.STAT_CHOICES})) }, 'slot_2_main_stat': { 'type': 'occurrences', 'total': qs.filter(slot=2).count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.filter(slot=2).values('main_stat').annotate( count=Count('main_stat')).filter( count__gt=min_count).order_by('main_stat')), {'main_stat': qs.model.STAT_CHOICES})) }, 'slot_4_main_stat': { 'type': 'occurrences', 'total': qs.filter(slot=4).count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.filter(slot=4).values('main_stat').annotate( count=Count('main_stat')).filter( count__gt=min_count).order_by('main_stat')), {'main_stat': qs.model.STAT_CHOICES})) }, 'slot_6_main_stat': { 'type': 'occurrences', 'total': qs.filter(slot=6).count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.filter(slot=6).values('main_stat').annotate( count=Count('main_stat')).filter( count__gt=min_count).order_by('main_stat')), {'main_stat': qs.model.STAT_CHOICES})) }, 'innate_stat': { 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.values('innate_stat').annotate( count=Count('pk')).filter( count__gt=min_count).order_by('innate_stat')), {'innate_stat': qs.model.STAT_CHOICES})) }, 'substats': { 'type': 'occurrences', 'total': len(all_substats), 'data': transform_to_dict( replace_value_with_choice( sorted([{ 'substat': k, 'count': v } for k, v in substat_counts.items()], key=lambda count: count['substat']), {'substat': qs.model.STAT_CHOICES}), ) }, 'max_efficiency': { 'type': 'histogram', 'width': 5, 'data': histogram(qs, 'max_efficiency', range(0, 100, 5), slice_on='quality'), }, 'value': { 'type': 'histogram', 'width': 500, 'data': histogram(qs, 'value', range(min_value, max_value, 500), slice_on='quality') } }
def get_monster_report(qs, total_log_count, **kwargs): if qs.count() == 0: return None min_count = kwargs.get('min_count', max(1, int(MINIMUM_THRESHOLD * total_log_count))) return { 'monsters': { # By unique monster 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( list( qs.values( 'monster', ).annotate( monster_name=Func( Concat(F('monster__element'), Value(' '), F('monster__name')), function='INITCAP', ), count=Count('pk'), ).filter(count__gt=min_count).order_by('-count') ), name_key='monster_name' ), }, 'family': { # By family 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( list( qs.values( family_id=F('monster__family_id'), name=F('monster__name'), ).annotate( count=Count('pk') ).filter( count__gt=min_count ).order_by('-count') ), name_key='name' ) }, 'nat_stars': { # By nat stars 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( list( qs.values( nat_stars=F('monster__natural_stars'), ).annotate( grade=Concat(Cast('monster__natural_stars', CharField()), Value('⭐')), count=Count('monster__natural_stars'), ).filter(count__gt=min_count).order_by('-count') ), name_key='grade' ) }, 'element': { # By element 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( replace_value_with_choice( list( qs.values( element=F('monster__element') ).annotate( element_cap=Func(F('monster__element'), function='INITCAP',), count=Count('pk') ).filter(count__gt=min_count).order_by('-count') ), {'element': Monster.ELEMENT_CHOICES} ), name_key='element_cap', ) }, 'awakened': { # By awakened/unawakened 'type': 'occurrences', 'total': qs.count(), 'data': transform_to_dict( list( qs.values( awakened=F('monster__is_awakened') ).annotate( count=Count('pk') ).filter(count__gt=min_count).order_by('-count') ), transform={ True: 'Awakened', False: 'Unawakened', } ), } }
def get_context_data(self, **kwargs): all_drops = get_drop_querysets(self.get_queryset()) recent_drops = { 'items': all_drops['items'].values( 'item', name=F('item__name'), icon=F('item__icon'), ).annotate( count=Sum('quantity') ).order_by('-count') if 'items' in all_drops else [], 'monsters': replace_value_with_choice( list(all_drops['monsters'].values( name=F('monster__name'), icon=F('monster__image_filename'), element=F('monster__element'), stars=F('grade'), is_awakened=F('monster__is_awakened'), can_awaken=F('monster__can_awaken'), ).annotate( count=Count('pk') ).order_by('-count')), {'element': Monster.ELEMENT_CHOICES}) if 'monsters' in all_drops else [], # 'monster_pieces': 'insert_data_here' if 'monster_pieces' in all_drops else [], 'runes': replace_value_with_choice( list(all_drops['runes'].values( 'type', 'quality', 'stars', ).annotate( count=Count('pk') ).order_by('-count') if 'runes' in all_drops else []), { 'type': RuneInstance.TYPE_CHOICES, 'quality': RuneInstance.QUALITY_CHOICES, } ), # 'secret_dungeons': 'insert_data_here' if 'runes' in all_drops else [], } dashboard_data = { 'energy_spent': { 'type': 'occurrences', 'total': self.get_log_count(), 'data': transform_to_dict( list( self.get_queryset().values( 'level' ).annotate( dungeon_name=Concat( F('level__dungeon__name'), Value(' B'), F('level__floor'), output_field=CharField() ), count=Sum('level__energy_cost'), ).order_by('-count') ), name_key='dungeon_name', ), }, 'recent_drops': recent_drops, } level_order = self.get_queryset().values('level').annotate( energy_spent=Sum('level__energy_cost') ).order_by('-energy_spent').values_list('level', flat=True) preserved_order = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(level_order)]) level_list = Level.objects.filter( pk__in=set(self.get_queryset().values_list('level', flat=True)) ).order_by(preserved_order).prefetch_related('dungeon')[:20] kwargs['dashboard'] = dashboard_data kwargs['level_list'] = level_list return super().get_context_data(**kwargs)