Initial commit

This commit is contained in:
marc
2025-03-09 20:00:54 +01:00
commit efd26ce19d
118 changed files with 78086 additions and 0 deletions

View File

View File

@@ -0,0 +1,6 @@
import enum
class Pages(enum.IntEnum):
Sessions = 0
Temes = 1

View File

@@ -0,0 +1,21 @@
import dataclasses
@dataclasses.dataclass(order=True)
class SearchMatch:
distance: float
ngram: str
@classmethod
def combine_matches(cls, matches):
ngrams, distances = zip(*((match.ngram, match.distance) for match in matches))
return cls(
ngram=', '.join(ngrams),
distance=sum(distances)/len(distances)
)
@dataclasses.dataclass
class QueryResult:
id: int
distance: float
ngram: str

View File

@@ -0,0 +1,35 @@
import dataclasses
import datetime
import enum
from typing import Optional
DEFAULT_START_TIME = datetime.time(20, 30)
DEFAULT_END_TIME = datetime.time(22, 30)
@dataclasses.dataclass
class SessionVenue:
name: Optional[str] = None
url: Optional[str] = None
@dataclasses.dataclass
class Session:
id: Optional[int] = None
date: datetime.date = dataclasses.field(default_factory=datetime.date.today)
start_time: datetime.time = DEFAULT_START_TIME
end_time: datetime.time = DEFAULT_END_TIME
venue: SessionVenue = dataclasses.field(default_factory=SessionVenue)
is_live: bool = False
@dataclasses.dataclass
class DateNames:
day_name: str
day: str
month_name: str
year: str
class SessionCols(enum.Enum):
DATE = "date"

74
folkugat_web/model/sql.py Normal file
View File

@@ -0,0 +1,74 @@
from __future__ import annotations
import dataclasses
import datetime
import enum
from abc import abstractmethod
from typing import Generic, Optional, Protocol, TypeVar
class Comparable(Protocol):
@abstractmethod
def __gt__(self: T, other: T, /) -> bool:
pass
@abstractmethod
def __ge__(self: T, other: T, /) -> bool:
pass
@abstractmethod
def __lt__(self: T, other: T, /) -> bool:
pass
@abstractmethod
def __le__(self: T, other: T, /) -> bool:
pass
T = TypeVar("T", bound=Comparable)
@dataclasses.dataclass
class Range(Generic[T]):
gt: Optional[T] = None
gte: Optional[T] = None
lt: Optional[T] = None
lte: Optional[T] = None
def lower_bound(self) -> Optional[tuple[T, bool]]:
if self.gt is None and self.gte is None:
return None
elif self.gt is not None and self.gte is not None:
lb = self.gt if (self.gt > self.gte) else self.gte
eq = self.gt < self.gte
return lb, eq
elif self.gt is not None:
return self.gt, False
elif self.gte is not None:
return self.gte, True
def upper_bound(self) -> Optional[tuple[T, bool]]:
if self.lt is None and self.lte is None:
return None
elif self.lt is not None and self.lte is not None:
ub = self.lt if (self.lt < self.lte) else self.lte
eq = self.lt > self.lte
return ub, eq
elif self.lt is not None:
return self.lt, False
elif self.lte is not None:
return self.lte, True
class Order(enum.Enum):
ASCENDING = 'ASC'
DESCENDING = 'DESC'
ColT = TypeVar("ColT")
@dataclasses.dataclass
class OrderCol(Generic[ColT]):
column: ColT
order: Order

123
folkugat_web/model/temes.py Normal file
View File

@@ -0,0 +1,123 @@
import dataclasses
import datetime
import enum
from typing import Optional
from folkugat_web.services import ngrams
NGrams = dict[int, list[str]]
class LinkType(enum.Enum):
SCORE = "score"
AUDIO = "audio"
OTHER = "other"
class LinkSubtype(enum.Enum):
# Score
PDF = "pdf"
IMAGE = "image"
# Audio
SPOTIFY = "spotify"
YOUTUBE = "youtube"
@dataclasses.dataclass
class Link:
type: LinkType
subtype: Optional[LinkSubtype]
url: str
title: str = ""
def to_dict(self):
return dict(
type=self.type.value,
subtype=self.subtype.value if self.subtype else None,
url=self.url,
title=self.title,
)
@classmethod
def from_dict(cls, d):
return cls(
type=LinkType(d["type"]),
subtype=LinkSubtype(d["subtype"]) if d["subtype"] else None,
url=d["url"],
title=d["title"],
)
class PropertyField(enum.Enum):
AUTOR = "autor"
TIPUS = "tipus"
COMPAS = "compàs"
ORIGEN = "orígen"
@dataclasses.dataclass
class Property:
field: PropertyField
value: str
def to_dict(self):
return dict(
field=self.field.value,
value=self.value,
)
@classmethod
def from_dict(cls, d):
return cls(
field=PropertyField(d["field"]),
value=d["value"],
)
@dataclasses.dataclass
class Lyrics:
title: str
content: str
def to_dict(self):
return dict(
title=self.title,
content=self.content,
)
@classmethod
def from_dict(cls, d):
return cls(
title=d["title"],
content=d["content"],
)
@dataclasses.dataclass
class Tema:
id: Optional[int] = None
# Info
title: str = ""
properties: list[Property] = dataclasses.field(default_factory=list)
links: list[Link] = dataclasses.field(default_factory=list)
lyrics: list[Lyrics] = dataclasses.field(default_factory=list)
# Search related
alternatives: list[str] = dataclasses.field(default_factory=list)
ngrams: NGrams = dataclasses.field(default_factory=dict)
hidden: bool = True
# Other info
modification_date: datetime.datetime = dataclasses.field(default_factory=datetime.datetime.now)
creation_date: datetime.datetime = dataclasses.field(default_factory=datetime.datetime.now)
def compute_ngrams(self):
self.ngrams = ngrams.get_text_ngrams(self.title, *self.alternatives)
def with_ngrams(self):
self.compute_ngrams()
return self
def scores(self):
return [link for link in self.links if link.type is LinkType.SCORE]
def audios(self):
return [link for link in self.links if link.type is LinkType.AUDIO]