diff --git a/src/api/serializers.py b/src/api/serializers.py index bbad60a25ca8a057c2da409cb7360f97f328f9af..e0a344ae4a481f727e1d5d525ca9f6a29684a07f 100644 --- a/src/api/serializers.py +++ b/src/api/serializers.py @@ -11,7 +11,6 @@ from core.models.assemblies import Assembly from core.models.badges import Badge, BadgeToken, BadgeTokenTimeConstraint from core.models.conference import Conference, ConferenceMember, ConferenceTrack from core.models.events import Event -from core.models.links import Link from core.models.messages import DirectMessage from core.models.metanavi import MetaNavItem from core.models.rooms import Room @@ -51,56 +50,6 @@ class ParameterisedHyperlinkedIdentityField(HyperlinkedIdentityField): return reverse(view_name, kwargs=kwargs, request=request, format=format) -class HubHyperlinkedIdentityField(HyperlinkedIdentityField): - """ - Represents the instance, or a property on the instance, using hyperlinking. - - lookup_fields is a tuple of tuples of the form: - ('model_field', 'url_parameter') - - taken from https://github.com/encode/django-rest-framework/issues/1024 - """ - - lookup_fields = (('pk', 'pk'),) - - def __init__(self, *args, **kwargs): - self.lookup_fields = kwargs.pop('lookup_fields', self.lookup_fields) - super().__init__(*args, **kwargs) - - def get_url(self, obj, view_name, request, format): # pylint: disable=redefined-builtin - """ - Given an object, return the URL that hyperlinks to the object. - - May raise a `NoReverseMatch` if the `view_name` and `lookup_field` - attributes are not configured to correctly match the URL conf. - """ - kwargs = {} - for model_field, url_param in self.lookup_fields: - attr = obj - for field in model_field.split('.'): - attr = getattr(attr, field) - kwargs[url_param] = attr - - from core.templatetags.hub_absolute import hub_absolute # pylint: disable=import-outside-toplevel - - # TODO: add request=request, format=format, - return hub_absolute(view_name, **kwargs, i18n=False) - - -class LinkRelatedField(serializers.RelatedField): - """ - A read only field that represents its targets using their - plain string representation. - """ - - def __init__(self, **kwargs): - kwargs['read_only'] = True - super().__init__(**kwargs) - - def to_representation(self, value: Link): - return value.to_dict() - - class ValidatingModelSerializer(serializers.ModelSerializer): def validate(self, data): instance = self.Meta.model(**{field: value for field, value in data.items() if field in self.Meta.model._meta.fields}) @@ -268,20 +217,17 @@ class BadgeTokenUpdateSerializer(BadgeTokenSerializer): class RoomSerializer(HubModelSerializer): assembly = serializers.SlugRelatedField(read_only=True, slug_field='slug') - links = LinkRelatedField( + links = serializers.StringRelatedField( many=True, read_only=True, ) - public_url = HubHyperlinkedIdentityField(view_name='plainui:room', lookup_fields=(('slug', 'slug'),)) - class Meta: model = Room read_only_fields = ['id'] fields = [ 'id', 'name', - 'slug', 'blocked', 'room_type', 'capacity', @@ -289,7 +235,6 @@ class RoomSerializer(HubModelSerializer): 'assembly', 'links', 'backend_link', - 'public_url', ] staff_only_fields = ['blocked', 'backend_link'] diff --git a/src/api/views/rooms.py b/src/api/views/rooms.py index 82c422a2d1478d65289a8e2f472bf33ad063005e..716e8795e55ec091a9b6322e0da51deab81d6445 100644 --- a/src/api/views/rooms.py +++ b/src/api/views/rooms.py @@ -14,7 +14,7 @@ class ConferenceRoomList(ConferenceSlugMixin, generics.ListAPIView): serializer_class = RoomSerializer def get_queryset(self, **kwargs): - return Room.objects.conference_accessible(conference=self.conference).order_by('official_room_order', 'name') + return Room.objects.conference_accessible(conference=self.conference).order_by('name') class ConferenceRoomDetail(ConferenceSlugMixin, generics.RetrieveAPIView): diff --git a/src/backoffice/templates/backoffice/schedule_source-detail.html b/src/backoffice/templates/backoffice/schedule_source-detail.html index ac55db261e5d5ae1c85e163e5d9af5eb09982be3..2122ae2de9557aecdc34277179b406c8cf5f687d 100644 --- a/src/backoffice/templates/backoffice/schedule_source-detail.html +++ b/src/backoffice/templates/backoffice/schedule_source-detail.html @@ -20,7 +20,7 @@ </div> <div class="card-body"> <p> - Assembly: <strong><a href="{% url 'backoffice:assembly-edit' pk=object.assembly.id %}">{{ object.assembly|default:"<em>WILDCARD</em>" }}</a></strong> + Assembly: <strong>{{ object.assembly|default:"<em>WILDCARD</em>" }}</strong> </p> <p> Type: <strong>{{ object.import_type }}</strong> @@ -108,10 +108,8 @@ {% for mapping in object.mappings.all %} <tr> <td>{{ mapping.get_mapping_type_display }}</td> - <td>{{ mapping.source_id|default:'-' }}</td> - <td> - <a href="{{ mapping.local_url }}">{{ mapping.local_id|default:'-' }}</a> - </td> + <td>{{ mapping.source_id|default:"-" }}</td> + <td>{{ mapping.local_id|default:"-" }}</td> <td>{{ mapping.skip|yesno }}</td> <td> </td> </tr> diff --git a/src/backoffice/templates/backoffice/schedule_source_import-detail.html b/src/backoffice/templates/backoffice/schedule_source_import-detail.html index ec3be03022ad3a310bf8c4ac15812b7502b0a77a..8b7e2c2597d29b28450036f892667917660171ba 100644 --- a/src/backoffice/templates/backoffice/schedule_source_import-detail.html +++ b/src/backoffice/templates/backoffice/schedule_source_import-detail.html @@ -95,7 +95,7 @@ {{ item.source_id|default:"-/-" }} </td> <td class="{% if item.action == "seen" %}text-muted{% elif item.action == "error" %}text-danger{% elif item.action == "missing" or item.action == "removed" %}text-warning{% elif item.action == "added" %}text-success{% endif %}"> - <a href="{{ item.local_url }}">{{ item.local_id|default:"-/-" }}</a> + {{ item.local_id|default:"-/-" }} </td> </tr> {% endfor %} diff --git a/src/core/admin.py b/src/core/admin.py index d9ee6d63023dc4ceef23e7dcd652ed3192127f44..8158cdcd2d8298de242c0e11d39fd529859fa8aa 100644 --- a/src/core/admin.py +++ b/src/core/admin.py @@ -750,11 +750,11 @@ class RoomShareAdmin(admin.ModelAdmin): class RoomAdmin(admin.ModelAdmin): - list_display = ['conference', 'assembly', 'name', 'room_type', 'blocked', 'official_room_order', 'id'] + list_display = ['conference', 'assembly', 'name', 'room_type', 'blocked'] list_display_links = ['name'] list_filter = ['conference', 'room_type', 'backend_status', 'blocked', 'is_official', 'is_public_fahrplan'] save_as = True - search_fields = ['assembly__name', 'name', 'slug', 'id'] + search_fields = ['assembly__name', 'name', 'slug'] inlines = [RoomLinkInline, RoomShareInline, TagsInline] readonly_fields = ['id', 'occupants', 'reserve_capacity'] ordering = ('-conference__id', F('assembly__is_official').desc(nulls_last=True), 'assembly__name', F('capacity').desc(nulls_last=True), 'name') diff --git a/src/core/models/links.py b/src/core/models/links.py index 65ded766dd94077ea2e2c23e69fe18d70a3f5a38..86764e7e409e67adef65819949d2b20d5600766f 100644 --- a/src/core/models/links.py +++ b/src/core/models/links.py @@ -5,7 +5,7 @@ from django.core.validators import URLValidator from django.db import models from django.utils.translation import gettext_lazy as _ -from core.utils import resolve_internal_url, resolve_link +from core.utils import resolve_link class Link(models.Model): @@ -62,14 +62,6 @@ class Link(models.Model): except ValidationError: raise ValidationError({'link': _('Link__link__must_be_url')}) - def to_dict(self): - return { - 'type': self.link_type, - 'name': self.name, - 'uri': self.link, - 'url': resolve_internal_url(self.link), - } - def __str__(self) -> str: return self.name diff --git a/src/core/models/rooms.py b/src/core/models/rooms.py index cef75f46a77b2b89f46a675ac1a6e2c22217d303..b54819c259eb740fe27d5810a9ede9ef16a73cac 100644 --- a/src/core/models/rooms.py +++ b/src/core/models/rooms.py @@ -273,11 +273,6 @@ class Room(BackendMixin, models.Model): return link.link return None - def get_absolute_url(self): - from core.templatetags.hub_absolute import hub_absolute # pylint: disable=import-outside-toplevel - - return hub_absolute('plainui:room', slug=self.slug, i18n=settings.ARCHIVE_MODE) - def __create_slug(self, extension='', max_length: int = 50): """ recursive function to generate a free room slug based on the room name @@ -506,13 +501,5 @@ class RoomLink(models.Model): if not resolve_internal_url(self.link, fallback_as_is=False): raise ValidationError({'link': _('RoomLink__link__must_be_url')}) - def to_dict(self): - return { - 'type': self.link_type, - 'name': self.name, - 'uri': self.link, - 'url': resolve_internal_url(self.link), - } - def __str__(self): return self.name diff --git a/src/core/models/schedules.py b/src/core/models/schedules.py index e9245a6fff58b973224c68ca2defedf3cc27e73f..aed616a497c2659faa6e4b1bf292f6dd723c06bc 100644 --- a/src/core/models/schedules.py +++ b/src/core/models/schedules.py @@ -348,9 +348,6 @@ class ScheduleSource(models.Model): ) logging.exception('Import on ScheduleSource %s encountered exception on creating mapping for %s "%s".', self.pk, item_type, item_source_id) - # ... and delete the incomplete (wrong) mapping if it was created - if new_mapping: - mapping.delete() return 'error' else: @@ -430,7 +427,7 @@ class ScheduleSource(models.Model): allow_track = cfg.get('import_tracks') or False # note down all existing rooms, events and speakers so that we can call out the missing ones - if self.assembly and cfg.get('missing_rooms') != 'ignore': + if self.assembly: expected_rooms = list(self.assembly.rooms.values_list('id', flat=True)) else: expected_rooms = list( @@ -693,18 +690,6 @@ class ScheduleSourceMapping(models.Model): # we don't know about that mapping type, bail out raise LocalObjectAccessViolation('Unknown mapping.') - @property - def local_url(self): - if self.mapping_type == self.MappingType.ROOM: - return Room.admin_url(self.local_id) - - if self.mapping_type == self.MappingType.EVENT: - return Event.admin_url(self.local_id) - if self.mapping_type == self.MappingType.SPEAKER: - return '' - - return '' - @property def local_object(self): if self._local_object is None: @@ -839,13 +824,17 @@ class ScheduleSourceImport(models.Model): # create list of unique errors for summary msgs = list({x['message'].split('\n')[0] for x in errors}) - stats = {t: sum(1 for x in activity if x['action'] == t) for t in ['added', 'changed', 'seen', 'deleted', 'missing', 'error', 'skipped']} - stats_str = ', '.join([f'{v}={k}' for (k, v) in stats.items() if v]) + ' \n' + ' \n'.join(msgs) - self.summary = f"{data.get('version') or ''}\nDONE: {stats_str}"[:200] + stats = ( + ', '.join( + (t + '=' + str(sum(1 for x in activity if x['action'] == t))) + for t in ['added', 'changed', 'seen', 'deleted', 'missing', 'error', 'skipped'] + ) + + ' \n' + + ' \n'.join(msgs) + ) + self.summary = f"{data.get('version') or ''}\nDONE: {stats}"[:200] - # add debug option to disable abort feature, as it might hide the actual error messages - if len(errors) > len(activity) / 2 and self.import_configuration.get('debug') is not True: - self.save(update_fields=['summary']) + if len(errors) > len(activity) / 2: raise Exception('Too many errors, aborting import: ' + stats) self.save(update_fields=['data', 'summary']) diff --git a/src/core/models/shared.py b/src/core/models/shared.py index 967c37ee60402d618d187cd832c8a2f91aefce67..77d69925df55fca9553719454a82412b1a4070de 100644 --- a/src/core/models/shared.py +++ b/src/core/models/shared.py @@ -3,12 +3,6 @@ from django.utils.translation import gettext_lazy as _ class BackendMixin(models.Model): - @classmethod - def admin_url(cls, pk): - from django.urls import reverse - - return reverse(f'admin:{cls._meta.app_label}_{cls._meta.model_name}_change', args=[pk]) - class Meta: abstract = True