Add highlight model to server

This commit is contained in:
Ramon Wenger 2024-01-11 09:48:56 +01:00
parent 4584cb860e
commit f3dc0e9b09
5 changed files with 162 additions and 33 deletions

View File

@ -10,7 +10,7 @@ from books.utils import are_solutions_enabled_for
from core.logger import get_logger
from core.mixins import HiddenAndVisibleForMixin
from notes.models import ContentBlockBookmark
from notes.schema import ContentBlockBookmarkNode
from notes.schema import ContentBlockBookmarkNode, HighlightNode
from rooms.models import ModuleRoomSlug
logger = get_logger(__name__)
@ -20,7 +20,7 @@ class TextBlockNode(graphene.ObjectType):
text = graphene.String()
def resolve_text(root, info, **kwargs):
return root['value']['text']
return root["value"]["text"]
class ContentNode(graphene.Union):
@ -30,30 +30,43 @@ class ContentNode(graphene.Union):
@classmethod
def resolve_type(cls, instance, info):
logger.info(instance)
if instance['type'] == 'text_block':
if instance["type"] == "text_block":
return TextBlockNode
def is_solution_and_hidden_for_user(type, user, module):
return type == 'solution' and not (are_solutions_enabled_for(user, module) or user.is_teacher())
return type == "solution" and not (
are_solutions_enabled_for(user, module) or user.is_teacher()
)
class ContentBlockNode(DjangoObjectType, HiddenAndVisibleForMixin):
mine = graphene.Boolean()
bookmarks = graphene.List(ContentBlockBookmarkNode)
original_creator = graphene.Field('users.schema.PublicUserNode')
original_creator = graphene.Field("users.schema.PublicUserNode")
instrument_category = graphene.Field(InstrumentCategoryNode)
path = graphene.String()
highlights = graphene.List(HighlightNode)
class Meta:
model = ContentBlock
only_fields = [
'slug', 'title', 'type', 'contents', 'hidden_for', 'visible_for', 'user_created'
"slug",
"title",
"type",
"contents",
"hidden_for",
"visible_for",
"user_created",
]
filter_fields = [
'slug', 'title',
"slug",
"title",
]
interfaces = (relay.Node, ContentBlockInterface,)
interfaces = (
relay.Node,
ContentBlockInterface,
)
convert_choices_to_enum = False
def resolve_mine(parent, info, **kwargs):
@ -64,18 +77,22 @@ class ContentBlockNode(DjangoObjectType, HiddenAndVisibleForMixin):
updated_raw_data = []
for content in self.contents.raw_data:
# only show solutions to teachers and students for whom their teachers have them enabled
if is_solution_and_hidden_for_user(content['type'], info.context.user, self.module):
logger.debug('Solution is hidden for this user')
if is_solution_and_hidden_for_user(
content["type"], info.context.user, self.module
):
logger.debug("Solution is hidden for this user")
continue
if content['type'] == 'content_list_item':
if content["type"] == "content_list_item":
_values = []
for index, list_block in enumerate(content['value']):
if is_solution_and_hidden_for_user(list_block['type'], info.context.user, self.module):
logger.debug('Solution is hidden for this user')
for index, list_block in enumerate(content["value"]):
if is_solution_and_hidden_for_user(
list_block["type"], info.context.user, self.module
):
logger.debug("Solution is hidden for this user")
continue
_values.append(process_module_room_slug_block(list_block))
content['value'] = _values
content["value"] = _values
content = process_module_room_slug_block(content)
updated_raw_data.append(content)
@ -85,16 +102,18 @@ class ContentBlockNode(DjangoObjectType, HiddenAndVisibleForMixin):
def resolve_bookmarks(self, info, **kwargs):
return ContentBlockBookmark.objects.filter(
user=info.context.user,
content_block=self
user=info.context.user, content_block=self
)
@staticmethod
def resolve_instrument_category(root: ContentBlock, info, **kwargs):
if root.type == ContentBlock.INSTRUMENT:
for content in root.contents.raw_data:
if content['type'] == 'instrument' or content['type'] == 'basic_knowledge':
_id = content['value']['basic_knowledge']
if (
content["type"] == "instrument"
or content["type"] == "basic_knowledge"
):
_id = content["value"]["basic_knowledge"]
instrument = BasicKnowledge.objects.get(id=_id)
category = instrument.new_type.category
return category
@ -103,17 +122,22 @@ class ContentBlockNode(DjangoObjectType, HiddenAndVisibleForMixin):
@staticmethod
def resolve_path(root: ContentBlock, info, **kwargs):
module = root.get_parent().get_parent()
return f'module/{module.slug}#{root.graphql_id}'
return f"module/{module.slug}#{root.graphql_id}"
@staticmethod
def resolve_highlights(root: ContentBlock, info, **kwargs):
return root.highlights.filter(user=info.context.user)
def process_module_room_slug_block(content):
if content['type'] == 'module_room_slug':
if content["type"] == "module_room_slug":
try:
module_room_slug = ModuleRoomSlug.objects.get(
title=content['value']['title'])
content['value'] = {
'title': content['value']['title'],
'slug': module_room_slug.slug
title=content["value"]["title"]
)
content["value"] = {
"title": content["value"]["title"],
"slug": module_room_slug.slug,
}
except ModuleRoomSlug.DoesNotExist:
pass

View File

@ -0,0 +1,52 @@
# Generated by Django 4.2.8 on 2024-01-09 15:07
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("books", "0045_alter_snapshot_objective_groups"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("notes", "0004_auto_20210322_1514"),
]
operations = [
migrations.CreateModel(
name="Highlight",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("content_index", models.IntegerField()),
("content_uuid", models.UUIDField()),
("paragraph_index", models.IntegerField()),
("start_position", models.IntegerField()),
("selection_length", models.IntegerField()),
("text", models.TextField()),
("color", models.CharField(max_length=50)),
(
"content_block",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="highlights",
to="books.contentblock",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to=settings.AUTH_USER_MODEL,
),
),
],
),
]

View File

@ -19,26 +19,50 @@ class Bookmark(models.Model):
class ContentBlockBookmark(Bookmark):
uuid = models.UUIDField(unique=False)
content_block = models.ForeignKey('books.ContentBlock', on_delete=models.CASCADE)
content_block = models.ForeignKey("books.ContentBlock", on_delete=models.CASCADE)
class Meta:
constraints = [
models.UniqueConstraint(fields=['uuid', 'content_block', 'user'], name='unique_content_bookmark_per_user')
models.UniqueConstraint(
fields=["uuid", "content_block", "user"],
name="unique_content_bookmark_per_user",
)
]
class ModuleBookmark(Bookmark):
module = models.ForeignKey('books.Module', on_delete=models.CASCADE)
module = models.ForeignKey("books.Module", on_delete=models.CASCADE)
class ChapterBookmark(Bookmark):
chapter = models.ForeignKey('books.Chapter', on_delete=models.CASCADE)
chapter = models.ForeignKey("books.Chapter", on_delete=models.CASCADE)
class InstrumentBookmark(Bookmark):
uuid = models.UUIDField(unique=False)
instrument = models.ForeignKey('basicknowledge.BasicKnowledge', on_delete=models.CASCADE)
instrument = models.ForeignKey(
"basicknowledge.BasicKnowledge", on_delete=models.CASCADE
)
class Meta:
constraints = [
models.UniqueConstraint(fields=['uuid', 'instrument', 'user'], name='unique_instrument_bookmark_per_user')
models.UniqueConstraint(
fields=["uuid", "instrument", "user"],
name="unique_instrument_bookmark_per_user",
)
]
class Highlight(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
content_block = models.ForeignKey(
"books.ContentBlock", on_delete=models.CASCADE, related_name="highlights"
)
# see highlight.ts for comments
content_index = models.IntegerField()
content_uuid = models.UUIDField()
paragraph_index = models.IntegerField()
start_position = models.IntegerField()
selection_length = models.IntegerField()
text = models.TextField()
color = models.CharField(max_length=50)

View File

@ -2,7 +2,14 @@ import graphene
from graphene import relay
from graphene_django import DjangoObjectType
from notes.models import Note, ContentBlockBookmark, ModuleBookmark, ChapterBookmark, InstrumentBookmark
from notes.models import (
Highlight,
Note,
ContentBlockBookmark,
ModuleBookmark,
ChapterBookmark,
InstrumentBookmark,
)
class NoteNode(DjangoObjectType):
@ -36,7 +43,6 @@ class ModuleBookmarkNode(DjangoObjectType):
fields = "__all__"
class ChapterBookmarkNode(DjangoObjectType):
note = graphene.Field(NoteNode)
@ -56,3 +62,11 @@ class InstrumentBookmarkNode(DjangoObjectType):
fields = "__all__"
filter_fields = []
interfaces = (relay.Node,)
class HighlightNode(DjangoObjectType):
class Meta:
model = Highlight
fields = "__all__"
filter_fields = []
interfaces = (relay.Node,)

View File

@ -511,6 +511,7 @@ type ContentBlockNode implements Node & ContentBlockInterface {
originalCreator: PublicUserNode
instrumentCategory: InstrumentCategoryNode
path: String
highlights: [HighlightNode]
}
type ContentBlockBookmarkNode implements Node {
@ -616,6 +617,20 @@ type InstrumentCategoryNode implements Node {
types: [InstrumentTypeNode]
}
type HighlightNode implements Node {
"""The ID of the object"""
id: ID!
user: PrivateUserNode!
contentBlock: ContentBlockNode!
contentIndex: Int!
contentUuid: UUID!
paragraphIndex: Int!
startPosition: Int!
selectionLength: Int!
text: String!
color: String!
}
type SnapshotObjectiveGroupNode implements Node {
"""The ID of the object"""
id: ID!