diff --git a/conference/admin.py b/conference/admin.py index 76c2db9cb..1eb3a1636 100644 --- a/conference/admin.py +++ b/conference/admin.py @@ -138,7 +138,17 @@ def wrapper(*args, **kwargs): def available_stats(self, conf): stats = [] - for path in settings.ADMIN_ATTENDEE_STATS: + stats_modules = ( + 'p3.stats.tickets_status', + 'p3.stats.conference_speakers', + 'p3.stats.conference_speakers_day', + 'p3.stats.speaker_status', + 'p3.stats.presence_days', + 'p3.stats.shirt_sizes', + 'p3.stats.diet_types', + 'p3.stats.pp_tickets', + ) + for path in stats_modules: func = utils.dotted_import(path) w = { 'get_data': self._stat_wrapper(func, conf), diff --git a/conference/debug_panel.py b/conference/debug_panel.py index 9c5850bd2..20bea09f0 100644 --- a/conference/debug_panel.py +++ b/conference/debug_panel.py @@ -39,7 +39,7 @@ set_early_bird_fare_dates, set_regular_fare_dates, ) -from conference.tickets import count_number_of_sold_training_tickets_including_combined_tickets +from conference.tickets import sold_training_tickets_including_combined_tickets def get_current_commit_hash(): @@ -90,9 +90,9 @@ def debug_panel_index(request): ('Python_Version', platform.python_version()), ('Conference_current', Conference.objects.current()), ('SOLD_TRAINING_TICKETS', - count_number_of_sold_training_tickets_including_combined_tickets( + sold_training_tickets_including_combined_tickets( conference_code=settings.CONFERENCE_CONFERENCE, - )), + ).count()), ] allowed_settings = [ diff --git a/conference/settings.py b/conference/settings.py index 8254d06e1..2132bd4a0 100644 --- a/conference/settings.py +++ b/conference/settings.py @@ -128,8 +128,6 @@ def _CONFERENCE_TICKETS(conf, ticket_type=None, fare_code=None): SCHEDULE_ATTENDEES = getattr(settings, 'CONFERENCE_SCHEDULE_ATTENDEES', lambda schedule, forecast=False: 0) -ADMIN_ATTENDEE_STATS = getattr(settings, 'CONFERENCE_ADMIN_ATTENDEE_STATS', ()) - X_SENDFILE = getattr(settings, 'CONFERENCE_X_SENDFILE', None) TALK_VIDEO_ACCESS = getattr(settings, 'CONFERENCE_TALK_VIDEO_ACCESS', lambda r, t: True) diff --git a/conference/tickets.py b/conference/tickets.py index 53839bf64..354a0d7b5 100644 --- a/conference/tickets.py +++ b/conference/tickets.py @@ -20,7 +20,7 @@ def reset_ticket_settings(ticket): return tc -def count_number_of_sold_training_tickets_including_combined_tickets(conference_code): +def sold_training_tickets_including_combined_tickets(conference_code): qs = Ticket.objects.filter( fare__conference=conference_code, frozen=False, @@ -37,4 +37,4 @@ def count_number_of_sold_training_tickets_including_combined_tickets(conference_ ] ) ) - return qs.count() + return qs diff --git a/p3/stats.py b/p3/stats.py index 33d54fefb..46657b99c 100644 --- a/p3/stats.py +++ b/p3/stats.py @@ -7,8 +7,8 @@ from p3 import models from conference import models as cmodels -from conference.models import Ticket, Speaker, Talk -from conference.tickets import count_number_of_sold_training_tickets_including_combined_tickets +from conference.models import Ticket, Speaker, Talk, TALK_STATUS +from conference.tickets import sold_training_tickets_including_combined_tickets def _create_option(id, title, total_qs, **kwargs): @@ -198,6 +198,30 @@ def tickets_status(conf, code=None): elif code == 'spam_recruiting': output = ticket_status_for_spam_recruiting(spam_recruiting) + elif code == 'training_tickets_sold': + output = ticket_status_for_training_tickets_including_combined(conference_code=conf) + + return output + + +def ticket_status_for_training_tickets_including_combined(conference_code): + output = { + 'columns': ( + ('ticket', 'Ticket'), + ('name', 'Attendee name'), + ('email', 'Email'), + ), + 'data': [], + } + tickets = sold_training_tickets_including_combined_tickets(conference_code=conference_code) + + for ticket in tickets: + output['data'].append({ + 'name': ticket.user.assopy_user.name(), + 'email': ticket.user.email, + 'ticket': ticket, + }) + return output @@ -374,7 +398,7 @@ def ticket_status_no_code(conf, multiple_assignments, orphan_tickets, spam_recru { 'id': 'training_tickets_sold', 'title': 'Sold training tickets (including combined)', - 'total': count_number_of_sold_training_tickets_including_combined_tickets(conference_code=conf), + 'total': sold_training_tickets_including_combined_tickets(conference_code=conf).count(), }, _create_option( 'tickets_with_unique_email', @@ -454,13 +478,20 @@ def conference_speakers(conf, code=None): accepted_spks = Speaker.objects.byConference(conf) not_scheduled = Speaker.objects\ .filter(talkspeaker__talk__in=Talk.objects\ - .filter(conference=conf, status='accepted', event=None))\ + .filter(conference=conf, status=TALK_STATUS.accepted, event=None))\ .distinct() + no_slides = Speaker.objects.filter( + Q(talkspeaker__talk__conference=conf) & + Q(talkspeaker__talk__status=TALK_STATUS.accepted) & + Q(talkspeaker__talk__slides='') & + Q(talkspeaker__talk__slides_url='') + ).distinct() if code is None: return [ _create_option('all_speakers', 'All speakers', all_spks), _create_option('accepted_speakers', 'Speakers with accepted talks', accepted_spks), _create_option('speakers_not_scheduled', 'Speakers with unscheduled accepted talks', not_scheduled), + _create_option('speakers_no_slides', 'Speakers who have not uploaded slides', no_slides), ] else: if code == 'all_speakers': @@ -469,10 +500,13 @@ def conference_speakers(conf, code=None): qs = accepted_spks elif code == 'speakers_not_scheduled': qs = not_scheduled + elif code == 'speakers_no_slides': + qs = no_slides output = { 'columns': ( ('name', 'Name'), ('email', 'Email'), + ('talks', 'Talks'), ), 'data': [], } @@ -481,12 +515,20 @@ def conference_speakers(conf, code=None): .select_related('user')\ .order_by('user__first_name', 'user__last_name') for x in qs: + talks = x.talks().filter(conference=conf, status=TALK_STATUS.accepted) + if code == 'speakers_no_slides': + talks = talks.filter(Q(talkspeaker__talk__slides='') & Q(talkspeaker__talk__slides_url='')) + data.append({ 'name': '%s %s' % ( reverse('admin:auth_user_change', args=(x.user_id,)), x.user.first_name, x.user.last_name), 'email': x.user.email, + 'talks': '
'.join([ + f"{talk.title}" + for talk in talks + ]), 'uid': x.user_id, }) return output diff --git a/pycon/settings.py b/pycon/settings.py index 333279831..935a17176 100644 --- a/pycon/settings.py +++ b/pycon/settings.py @@ -715,18 +715,6 @@ def CONFERENCE_SCHEDULE_ATTENDEES(schedule, forecast): return 0 -CONFERENCE_ADMIN_ATTENDEE_STATS = ( - 'p3.stats.tickets_status', - 'p3.stats.conference_speakers', - 'p3.stats.conference_speakers_day', - 'p3.stats.speaker_status', - 'p3.stats.presence_days', - 'p3.stats.shirt_sizes', - 'p3.stats.diet_types', - 'p3.stats.pp_tickets', -) - - CONFERENCE_TICKET_BADGE_ENABLED = True CONFERENCE_TICKET_BADGE_PROG_ARGS = ['-e', '0', '-p', 'A4', '-n', '1']