Add CSV exporter for the sessions list to token options
authorSteve Singer <^Ceve@ssinger.info>
Wed, 3 Sep 2025 09:28:36 +0000 (11:28 +0200)
committerMagnus Hagander <magnus@hagander.net>
Wed, 3 Sep 2025 09:30:46 +0000 (11:30 +0200)
This way a static site (for example) can pull down all sessions and
their data.

postgresqleu/confreg/backendviews.py
postgresqleu/confreg/migrations/0023_accesstokens.py
postgresqleu/confreg/models.py

index 03f3ae7b552eeeab0bd1deb421e4465e217330e2..0388c097186d799925387c89530b98997ce6e2c7 100644 (file)
@@ -9,6 +9,7 @@ from django.utils import timezone
 from django.conf import settings
 
 import csv
+import io
 import json
 from collections import OrderedDict
 
@@ -25,7 +26,7 @@ from .jinjafunc import JINJA_TEMPLATE_ROOT
 from .jinjapdf import render_jinja_ticket, render_jinja_badges
 from .util import send_conference_mail, get_conference_or_404, send_conference_notification
 
-from .models import Conference, ConferenceSeries
+from .models import Conference, ConferenceSeries, ConferenceSession
 from .models import ConferenceRegistration
 from .models import Speaker
 from .models import PrepaidBatch
@@ -976,12 +977,53 @@ ORDER BY name""", {'confid': conference.id})
             return sponsorclaimsfile(conference, subrequest.lstrip('/'))
         else:
             return _structured_tokendata(sponsorclaimsdata(conference), dataformat)
+    elif datatype == 'sessions':
+        sessiondata(conference, writer)
     else:
         raise Http404()
 
     return writer.response
 
 
+def csvembed(iter):
+    f = io.StringIO()
+    writer = csv.writer(f, lineterminator='', delimiter=';')
+    writer.writerow(iter)
+    return f.getvalue()
+
+
+def sessiondata(conference, writer):
+    result = []
+    status_filter = []
+    sessions = ConferenceSession.objects.filter(conference=conference)
+    header = ['id', 'title', 'shorttitle', 'abstract', 'status', 'speaker', 'company',
+              'email', 'track', 'starttime', 'endtime', 'recordingconsent', 'room', 'submissionnote']
+    writer.columns(header)
+    writer.grouping = False
+    for s in sessions:
+        speaker_names = csvembed(map(lambda spk: spk.name, s.speaker.all()))
+        speaker_emails = csvembed(map(lambda spk: spk.email, s.speaker.all()))
+        speaker_companies = csvembed(map(lambda spk: spk.company, s.speaker.all()))
+        row = [
+            s.id,
+            s.title,
+            s.shorttitle,
+            s.abstract,
+            s.status_string,
+            speaker_names,
+            speaker_companies,
+            speaker_emails,
+            None if s.track is None else s.track.trackname,
+            s.starttime,
+            s.endtime,
+            s.recordingconsent,
+            None if s.room is None else s.room.roomname,
+            s.submissionnote,
+        ]
+        result.append(row)
+    writer.write_rows(result)
+
+
 def registration_dashboard_send_email(request, urlname):
     conference = get_authenticated_conference(request, urlname)
 
index f1c7730876648f6c5d115c875e81cd7dd76c4717..ac4baeb45e8994e3c6acf7d1c1d2c4f72c2bb86c 100644 (file)
@@ -18,7 +18,7 @@ class Migration(migrations.Migration):
                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                 ('token', models.CharField(max_length=200)),
                 ('description', models.TextField()),
-                ('permissions', postgresqleu.util.forms.ChoiceArrayField(base_field=models.CharField(max_length=32, choices=[('regtypes', 'Registration types and counters'), ('discounts', 'Discount codes'), ('discountspublic', 'Public discount codes'), ('vouchers', 'Voucher codes'), ('sponsors', 'Sponsors and counts'), ('addopts', 'Additional options and counts'), ('schedule', 'Schedule JSON'), ('sponsorlevels', 'Sponsor level metadata'), ('sponsorclaims', 'Sponsor claimed benefits')]), size=None)),
+                ('permissions', postgresqleu.util.forms.ChoiceArrayField(base_field=models.CharField(max_length=32, choices=[('regtypes', 'Registration types and counters'), ('discounts', 'Discount codes'), ('discountspublic', 'Public discount codes'), ('vouchers', 'Voucher codes'), ('sponsors', 'Sponsors and counts'), ('addopts', 'Additional options and counts'), ('schedule', 'Schedule JSON'), ('sponsorlevels', 'Sponsor level metadata'), ('sponsorclaims', 'Sponsor claimed benefits'), ('sessions', 'Sessions')]), size=None)),
                 ('conference', models.ForeignKey(to='confreg.Conference', on_delete=models.CASCADE)),
             ],
         ),
index 0366990c2b850c86d7531a2918578769cb110ea5..2db0ef4a4c297f45204f0260e8a58122b4e1d79b 100644 (file)
@@ -1556,6 +1556,7 @@ AccessTokenPermissions = (
     ('schedule', 'Schedule JSON'),
     ('sponsorlevels', 'Sponsor level metadata'),
     ('sponsorclaims', 'Sponsor claimed benefits'),
+    ('sessions', 'Sessions')
 )