diff --git a/src/api/tests/schedule.py b/src/api/tests/schedule.py index 66424c5ac2f90ebdfe2f302149aab75b4afd7374..ea04dd5f52853a99f4cc718ee3d7c3a9eaed197e 100644 --- a/src/api/tests/schedule.py +++ b/src/api/tests/schedule.py @@ -65,6 +65,9 @@ class ScheduleTest(TestCase): self.assertIsNotNone(event.schedule_end) def test_push_new_event(self): + another_room = Room(conference=self.conf, assembly=self.assembly, room_type=Room.RoomType.STAGE) + another_room.save() + update = { "url": "https://fahrplan.events.ccc.de/rc3/2020/Fahrplan/events/11583.html", "id": 11583, @@ -74,6 +77,7 @@ class ScheduleTest(TestCase): "start": "12:20", "duration": "01:30", "room": "foo room", + "room_id": str(another_room.pk), "slug": "rc3-11583-rc3_eroffnung", "title": "#rC3 Er\u00f6ffnung", "subtitle": "", @@ -103,3 +107,5 @@ class ScheduleTest(TestCase): self.assertTrue('rC3' in event.name, f'Expected "rC3" in event name "{event.name}".') self.assertEqual(timedelta(minutes=90), event.schedule_duration) self.assertIsNotNone(event.schedule_end) + + self.assertEqual(another_room.pk, event.room_id, 'Expected import to prefer "room_id" over "room".') diff --git a/src/api/views/schedule.py b/src/api/views/schedule.py index 65ecbcd9b25f0001b9c668be47195fb44e0d2b33..c3d495c270201b6a4d38648fd1cae3843d0e15d7 100644 --- a/src/api/views/schedule.py +++ b/src/api/views/schedule.py @@ -10,6 +10,7 @@ from rest_framework.response import Response from rest_framework.views import APIView import pytz +from core.models.assemblies import Assembly from core.models.events import Event from core.models.rooms import Room from core.models.conference import ConferenceTrack @@ -97,39 +98,65 @@ class EventSchedule(ConferenceSlugMixin, APIView): logger.warning('Event schedule POST: id %s did not exist yet, creating.', pk) try: - if 'guid' in event: - if event['guid'] != str(obj.pk): - logger.warning('Attempted update of event %s with guid "%s".', obj.pk, event["guid"]) - return JsonResponse({'error': 'GUID mismatch.'}) + if (event_guid := event.get('guid')) is not None: + if event_guid != str(obj.pk): + logger.warning('Attempted update of event %s with guid "%s".', obj.pk, event_guid) + return JsonResponse({'error': 'GUID mismatch.'}, status=400) - if 'slug' in event: - obj.slug = event['slug'] + if (event_slug := event.get('slug')) is not None: + obj.slug = event_slug + + if (event_roomid := event.get('room_id')) is not None: + obj.room = Room.objects.get(conference=self.conference, pk=event_roomid) + + elif (event_room := event.get('room')) is not None: + try: + obj.room = Room.objects.get(conference=self.conference, name__iexact=event_room) + except Room.MultipleObjectsReturned: + return JsonResponse({'error': 'Room name is not unique, please provide room_id!'}, status=400) + + if (event_assemblyid := event.get('assembly_id')) is not None: + obj.assembly = Assembly.objects.get(conference=self.conference, pk=event_assemblyid) + + elif (event_assemblyslug := event.get('assembly_slug')) is not None: + obj.assembly = Assembly.objects.get(conference=self.conference, slug__iexact=event_assemblyslug) + + if obj.assembly_id is None: + if obj.room_id is not None: + obj.assembly = obj.room.assembly + else: + return JsonResponse({'error': 'Assembly association missing, please provide assembly_id or a valid room.'}, status=400) - obj.room = Room.objects.get(conference=self.conference, name__iexact=event['room']) - obj.assembly = obj.room.assembly obj.kind = 'assembly' if not obj.room.assembly.is_official else 'official' obj.is_public = True - if 'title' in event: - obj.name = event['title'] + if (event_title := event.get('title')) is not None: + obj.name = event_title - if 'language' in event: - obj.language = event['language'] + if (event_language := event.get('language')) is not None: + obj.language = event_language - obj.description = str(event['abstract']) + "\n\n" + str(event['description']) + if (event_abstract := event.get('abstract')) is not None and (event_description := event.get('description')) is not None: + obj.description = str(event_abstract) + '\n\n' + str(event_description) - obj.schedule_start = parse_datetime(event['date']) - obj.schedule_duration = schedulexml_time_to_timedelta(event['duration']) + if (event_date := event.get('date')) is not None: + obj.schedule_start = parse_datetime(event_date) + if (event_duration := event.get('duration')) is not None: + obj.schedule_duration = schedulexml_time_to_timedelta(event_duration) - obj.track = ConferenceTrack.objects.get(conference=self.conference, name__iexact=event['track']) + if (event_track := event.get('track')) is not None: + obj.track = ConferenceTrack.objects.get(conference=self.conference, name__iexact=event_track) obj.additional_data = filter_additional_data(event) + except Assembly.DoesNotExist: + return Response({'error': f'Assembly {event.get("assembly_id")}/{event.get("assembly_slug")} does not exist.'}, status=400) + except Room.DoesNotExist: - return Response({'error': 'Room {} does not exist'.format(event['room'])}, status=400) + return Response({'error': f'Room {event.get("room_id")}/{event.get("room")} does not exist.'}, status=400) except ConferenceTrack.DoesNotExist: - return Response({'error': 'Track {} does not exist'.format(event['track'])}, status=400) + return Response({'error': f'Track {event.get("track_id")}/{event.get("track")} does not exist.'}, status=400) obj.save() logger.info('Event %s updated via POST by %s', obj, request.user)