Skip to content

Commit

Permalink
feature(study-search): table model review (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
laurent-laporte-pro committed Jan 31, 2024
1 parent 42a0575 commit 3001d5f
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 19 deletions.
141 changes: 141 additions & 0 deletions antarest/study/css4_colors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
"""
CSS Color Module Level 4
[Color keywords](https://www.w3.org/TR/css-color-4/#color-keywords)
"""

COLOR_NAMES = (
"AliceBlue",
"AntiqueWhite",
"Aquamarine",
"Aqua",
"Beige",
"Bisque",
"Black",
"BlanchedAlmond",
"BlueViolet",
"Blue",
"Brown",
"BurlyWood",
"CadetBlue",
"Chartreuse",
"Chocolate",
"Coral",
"CornflowerBlue",
"Cornsilk",
"Crimson",
"DarkBlue",
"DarkGoldenrod",
"DarkGray",
"DarkGreen",
"DarkKhaki",
"DarkOliveGreen",
"DarkOrange",
"DarkOrchid",
"DarkSalmon",
"DarkSeaGreen",
"DarkSlateBlue",
"DarkSlateGray",
"DarkTurquoise",
"DarkViolet",
"DeepPink",
"DeepSkyBlue",
"DimGray",
"DodgerBlue",
"FireBrick",
"ForestGreen",
"Gainsboro",
"Goldenrod",
"Gold",
"Gray",
"GreenYellow",
"Green",
"Honeydew",
"HotPink",
"IndianRed",
"Indigo",
"Ivory",
"Khaki",
"LavenderBlush",
"Lavender",
"LawnGreen",
"LemonChiffon",
"LightBlue",
"LightCoral",
"LightCyan",
"LightGoldenrod",
"LightGray",
"LightGreen",
"LightPink",
"LightSalmon",
"LightSeaGreen",
"LightSkyBlue",
"LightSlateGray",
"LightSteelBlue",
"LightYellow",
"LimeGreen",
"Lime",
"Linen",
"Magenta",
"Maroon",
"MediumAquamarine",
"MediumBlue",
"MediumOrchid",
"MediumPurple",
"MediumSeaGreen",
"MediumSlateBlue",
"MediumSpringGreen",
"MediumTurquoise",
"MediumVioletRed",
"MidnightBlue",
"MintCream",
"MistyRose",
"Moccasin",
"NavajoWhite",
"Navy",
"OldLace",
"OliveDrab",
"Olive",
"OrangeRed",
"Orange",
"Orchid",
"PaleGoldenrod",
"PaleGreen",
"PaleTurquoise",
"PaleVioletRed",
"PapayaWhip",
"PeachPuff",
"Peru",
"Pink",
"Plum",
"PowderBlue",
"Purple",
"Red",
"RosyBrown",
"RoyalBlue",
"SaddleBrown",
"Salmon",
"SandyBrown",
"SeaGreen",
"Seashell",
"Sienna",
"Silver",
"SkyBlue",
"SlateBlue",
"SlateGray",
"Snow",
"SpringGreen",
"SteelBlue",
"Tan",
"Teal",
"Thistle",
"Tomato",
"Turquoise",
"Violet",
"Wheat",
"WhiteSmoke",
"White",
"YellowGreen",
"Yellow",
)
"""List of CSS4 color names used to style tags."""
23 changes: 11 additions & 12 deletions antarest/study/model.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import dataclasses
import enum
import hashlib
import secrets
import typing as t
import uuid
from datetime import datetime, timedelta
Expand All @@ -24,6 +24,7 @@
from antarest.core.model import PublicMode
from antarest.core.persistence import Base
from antarest.login.model import Group, GroupDTO, Identity
from antarest.study.css4_colors import COLOR_NAMES

if t.TYPE_CHECKING:
# avoid circular import
Expand Down Expand Up @@ -63,12 +64,12 @@ class StudyTag(Base): # type:ignore
"""

__tablename__ = "study_tag"
__table_args__ = (PrimaryKeyConstraint("study_id", "tag"),)

# review: vérifier à l'aide d'un TU que le ondelete="CASCADE" fonctionne bien
study_id: str = Column(String(36), ForeignKey("study.id", ondelete="CASCADE"), index=True, nullable=False)
tag: str = Column(String, ForeignKey("tag.label", ondelete="CASCADE"), index=True, nullable=False)

__table_args__ = (PrimaryKeyConstraint("study_id", "tag"),)

def __str__(self) -> str:
return f"[Study-Tag-Pair] study_id={self.study_id}, tag={self.tag}"

Expand All @@ -81,18 +82,14 @@ class Tag(Base): # type:ignore
__tablename__ = "tag"

label = Column(String, primary_key=True, index=True)
color: str = Column(String(7), index=True)
color: str = Column(String(20), index=True, default=lambda: secrets.choice(COLOR_NAMES))

# review: faut-il vraiment un lambda ici ?
studies: t.List["Study"] = relationship("Study", secondary=lambda: StudyTag.__table__, back_populates="tags")

def __str__(self) -> str:
return f"[Tag] label={self.label}, css-color-code={self.color}"

@staticmethod
def generate_random_color_code(label: str) -> str:
"""
Generate a random CSS color code.
"""
return "#" + (hashlib.sha256(label.encode()).hexdigest()[:6]).upper()


class StudyContentStatus(enum.Enum):
VALID = "VALID"
Expand Down Expand Up @@ -154,7 +151,9 @@ class Study(Base): # type: ignore
public_mode = Column(Enum(PublicMode), default=PublicMode.NONE)
owner_id = Column(Integer, ForeignKey(Identity.id), nullable=True, index=True)
archived = Column(Boolean(), default=False, index=True)
tags: t.List[Tag] = relationship(Tag, secondary=lambda: StudyTag.__table__, backref="studies", cascade="")

# review: faut-il vraiment un lambda ici ?
tags: t.List[Tag] = relationship(Tag, secondary=lambda: StudyTag.__table__, back_populates="studies")
owner = relationship(Identity, uselist=False)
groups = relationship(Group, secondary=lambda: groups_metadata, cascade="")
additional_data = relationship(
Expand Down
14 changes: 9 additions & 5 deletions antarest/study/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,12 @@ def _update_study_from_cache_listing(self, study: Study) -> None:
logger.error("Failed to invalidate listing cache", exc_info=e)

def update_tags(self, tags: t.Set[str]) -> None:
if tags:
existing_tags = self.session.query(Tag).filter(Tag.label.in_(tags)).all()
new_tags = tags.difference(map(lambda x: x.label, existing_tags))
self.session.add_all([Tag(label=tag, color=Tag.generate_random_color_code(tag)) for tag in new_tags])
self.session.commit()
existing_labels = set(self.session.query(Tag.label).filter(Tag.label.in_(tags)))
new_tags = tags - existing_labels
self.session.add_all([Tag(label=tag) for tag in new_tags])
self.session.commit()

def update_study_tags(self, study_id: str, labels: t.Set[str]) -> None:
study = self.session.query(Study).get(study_id)
study.tags = [Tag(label=tag) for tag in labels]
self.session.commit()
11 changes: 9 additions & 2 deletions antarest/study/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,9 +564,16 @@ def update_study_information(

self.repository.session.query(StudyTag).filter(StudyTag.study_id == uuid).delete()
self.repository.session.commit()

# review: On peut simplifier la requête en récupérant uniquement les labels
existing_tags = self.repository.session.query(Tag).filter(Tag.label.in_(new_metadata.tags)).all()
new_tags = set(new_metadata.tags).difference(map(lambda x: x.label, existing_tags))
self.repository.session.add_all([Tag(label=tag, color=Tag.generate_random_color_code(tag)) for tag in new_tags])

# review: Il faudrait mettre à jour `study` en utilisant leds relationships
# study.tags = [mettre la liste des tags]
self.repository.session.commit()

self.repository.session.add_all([Tag(label=tag) for tag in new_tags])
self.repository.session.commit()
self.repository.session.add_all([StudyTag(study_id=uuid, tag=tag) for tag in metadata_patch.tags])
self.repository.session.commit()
Expand Down Expand Up @@ -647,7 +654,7 @@ def create_study(
updated_at=datetime.utcnow(),
version=version or NEW_DEFAULT_STUDY_VERSION,
additional_data=StudyAdditionalData(author=author),
tags=[Tag(label=tag, color=Tag.generate_random_color_code(tag)) for tag in tags] if tags else [],
tags=[Tag(label=tag) for tag in tags] if tags else [],
)

raw = self.storage_service.raw_study_service.create(raw)
Expand Down

0 comments on commit 3001d5f

Please sign in to comment.