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']