Skip to content

Commit 6cc8cca

Browse files
committed
WIP: implements backend, frontend UX, and basic UI for community library
1 parent e35f2ee commit 6cc8cca

31 files changed

Lines changed: 3397 additions & 70 deletions

app/api/serializers.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@
88
import phpserialize
99
from core.models import (
1010
Asset,
11+
CommunityLibraryEntry,
1112
DateRange,
13+
LibraryReport,
1214
Log,
1315
LogPlay,
1416
LogStorage,
1517
Lti,
1618
Notification,
1719
ObjectPermission,
1820
UserExtraAttempts,
21+
UserLike,
1922
UserSettings,
2023
Widget,
2124
WidgetInstance,
@@ -377,6 +380,24 @@ def update(self, widget_instance, validated_data):
377380
id = serializers.CharField(
378381
required=False
379382
) # Model's save function will auto-generate an ID if it is empty
383+
library_entry = serializers.SerializerMethodField()
384+
385+
def get_library_entry(self, instance):
386+
entry = CommunityLibraryEntry.objects.filter(instance=instance).first()
387+
if entry is None:
388+
return None
389+
return {
390+
"id": entry.id,
391+
"category": entry.category,
392+
"category_display": entry.get_category_display(),
393+
"course_level": entry.course_level,
394+
"course_level_display": entry.get_course_level_display(),
395+
"featured": entry.featured,
396+
"is_banned": entry.is_banned,
397+
"report_count": entry.report_count,
398+
"copy_count": entry.copy_count,
399+
"like_count": entry.like_count,
400+
}
380401

381402
class Meta:
382403
model = WidgetInstance
@@ -393,6 +414,8 @@ class Meta:
393414
"attempts",
394415
"is_deleted",
395416
"embedded_only",
417+
"is_shared",
418+
"library_entry",
396419
"widget",
397420
"widget_id",
398421
"preview_url",
@@ -873,3 +896,79 @@ class PlayStorageSaveSerializer(serializers.Serializer):
873896
queryset=LogPlay.objects.all(), required=True
874897
)
875898
logs = serializers.JSONField()
899+
900+
901+
class CommunityLibraryEntrySerializer(serializers.ModelSerializer):
902+
instance_id = serializers.CharField(source="instance.id", read_only=True)
903+
instance_name = serializers.SerializerMethodField()
904+
widget = WidgetSerializer(source="instance.widget", read_only=True)
905+
owner_display_name = serializers.SerializerMethodField()
906+
category_display = serializers.CharField(
907+
source="get_category_display", read_only=True
908+
)
909+
course_level_display = serializers.CharField(
910+
source="get_course_level_display", read_only=True
911+
)
912+
latest_snapshot_id = serializers.SerializerMethodField()
913+
user_has_liked = serializers.SerializerMethodField()
914+
last_reported_at = serializers.SerializerMethodField()
915+
916+
class Meta:
917+
model = CommunityLibraryEntry
918+
fields = [
919+
"id",
920+
"instance_id",
921+
"instance_name",
922+
"widget",
923+
"owner_display_name",
924+
"category",
925+
"category_display",
926+
"course_level",
927+
"course_level_display",
928+
"featured",
929+
"copy_count",
930+
"like_count",
931+
"report_count",
932+
"is_banned",
933+
"latest_snapshot_id",
934+
"user_has_liked",
935+
"created_at",
936+
"last_reported_at",
937+
]
938+
939+
def get_instance_name(self, entry):
940+
snapshot = entry.snapshots.order_by("-created_at").first()
941+
return snapshot.name
942+
943+
def get_latest_snapshot_id(self, entry):
944+
snapshot = entry.snapshots.order_by("-created_at").first()
945+
return snapshot.id
946+
947+
def get_owner_display_name(self, entry):
948+
user = entry.instance.user
949+
first = user.first_name or ""
950+
last_initial = f"{user.last_name[0]}." if user.last_name else ""
951+
return f"{first} {last_initial}".strip()
952+
953+
def get_last_reported_at(self, entry):
954+
latest_report = entry.reports.order_by("-created_at").first()
955+
return latest_report.created_at if latest_report else None
956+
957+
def get_user_has_liked(self, entry):
958+
request = self.context.get("request")
959+
return UserLike.objects.filter(user=request.user, entry=entry).exists()
960+
961+
962+
class LibraryReportSerializer(serializers.ModelSerializer):
963+
class Meta:
964+
model = LibraryReport
965+
fields = ["reason", "details"]
966+
967+
968+
class PublishToLibrarySerializer(serializers.Serializer):
969+
category = serializers.ChoiceField(choices=CommunityLibraryEntry.CATEGORY_CHOICES)
970+
course_level = serializers.ChoiceField(
971+
choices=[("", "")] + CommunityLibraryEntry.COURSE_LEVEL_CHOICES,
972+
required=False,
973+
default="",
974+
)

0 commit comments

Comments
 (0)