refactor: package structure

This commit is contained in:
283375 2023-08-24 23:16:18 +08:00
parent 1d3d4277f6
commit 2d4135fdfe
Signed by: 283375
SSH Key Fingerprint: SHA256:UcX0qg6ZOSDOeieKPGokA5h7soykG61nz2uxuQgVLSk
8 changed files with 22 additions and 239 deletions

View File

View File

View File

@ -0,0 +1,20 @@
import dataclasses
from typing import List
@dataclasses.dataclass
class ExternalScoreItem:
song_id: str
rating_class: int
score: int
pure: int = -1
far: int = -1
lost: int = -1
max_recall: int = -1
clear_type: int = -1
time: int = -1
class ExternalScoreSource:
def get_score_items(self) -> List[ExternalScoreItem]:
...

View File

@ -1,24 +1,7 @@
import dataclasses
import sqlite3
from typing import List, Union
from typing import Union
@dataclasses.dataclass
class ExternalScoreItem:
song_id: str
rating_class: int
score: int
pure: int = -1
far: int = -1
lost: int = -1
max_recall: int = -1
clear_type: int = -1
time: int = -1
class ExternalScoreSource:
def get_score_items(self) -> List[ExternalScoreItem]:
...
from .common import ExternalScoreItem, ExternalScoreSource
class St3ScoreSource(ExternalScoreSource):

View File

@ -1,148 +0,0 @@
from typing import Dict, List, TypedDict
class VersionSqls(TypedDict):
init: List[str]
update: List[str]
INIT_SQLS: Dict[int, VersionSqls] = {
1: {
"init": [
# region CREATE
"""
CREATE TABLE IF NOT EXISTS charts (
song_id TEXT NOT NULL,
rating_class INTEGER NOT NULL,
name_en TEXT NOT NULL,
name_jp TEXT,
artist TEXT NOT NULL,
bpm TEXT NOT NULL,
bpm_base REAL NOT NULL,
package_id TEXT NOT NULL,
time INTEGER,
side INTEGER NOT NULL,
world_unlock BOOLEAN NOT NULL,
remote_download BOOLEAN,
bg TEXT NOT NULL,
date INTEGER NOT NULL,
version TEXT NOT NULL,
difficulty INTEGER NOT NULL,
rating INTEGER NOT NULL,
note INTEGER NOT NULL,
chart_designer TEXT,
jacket_designer TEXT,
jacket_override BOOLEAN NOT NULL,
audio_override BOOLEAN NOT NULL,
PRIMARY KEY (song_id, rating_class)
)
""",
"""
CREATE TABLE IF NOT EXISTS aliases (
song_id TEXT NOT NULL,
alias TEXT NOT NULL
)
""",
"""
CREATE TABLE IF NOT EXISTS packages (
package_id TEXT NOT NULL,
name TEXT NOT NULL
)
""",
"""
CREATE TABLE IF NOT EXISTS scores (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
song_id TEXT NOT NULL,
rating_class INTEGER NOT NULL,
score INTEGER NOT NULL,
pure INTEGER,
far INTEGER,
lost INTEGER,
time INTEGER NOT NULL,
max_recall INTEGER,
clear_type INTEGER,
FOREIGN KEY (song_id, rating_class) REFERENCES charts(song_id, rating_class) ON UPDATE CASCADE ON DELETE NO ACTION
)
""",
"""
CREATE TABLE IF NOT EXISTS properties (
key TEXT NOT NULL UNIQUE,
value TEXT NOT NULL
)
""",
"""
CREATE VIEW IF NOT EXISTS calculated AS
SELECT
scores.id,
scores.song_id,
scores.rating_class,
scores.score,
scores.pure,
scores.far,
scores.lost,
scores.time,
charts.rating,
charts.note,
score - FLOOR(( pure * 10000000.0 / note ) + ( far * 0.5 * 10000000.0 / note )) AS pure_small,
CASE
WHEN score >= 10000000 THEN
rating / 10.0 + 2
WHEN score >= 9800000 THEN
rating / 10.0 + 1 + ( score - 9800000 ) / 200000.0
ELSE MAX(( rating / 10.0 ) + ( score - 9500000 ) / 300000.0, 0)
END AS potential
FROM
scores
LEFT JOIN charts ON scores.rating_class = charts.rating_class
AND scores.song_id = charts.song_id
GROUP BY
scores.id
""",
"""
CREATE VIEW IF NOT EXISTS bests AS
SELECT
c.song_id,
c.rating_class,
MAX(c.potential) AS potential
FROM
calculated c
GROUP BY
c.song_id,
c.rating_class
ORDER BY
potential DESC
""",
"""
CREATE VIEW IF NOT EXISTS calculated_potential AS
SELECT
AVG(b30_ptt) AS b30
FROM
( SELECT potential AS b30_ptt FROM bests ORDER BY potential DESC LIMIT 30 )
""",
"""
CREATE VIEW IF NOT EXISTS song_id_names AS
SELECT song_id, name
FROM (
SELECT song_id, alias AS name FROM aliases
UNION ALL
SELECT song_id, song_id AS name FROM charts
UNION ALL
SELECT song_id, name_en AS name FROM charts
UNION ALL
SELECT song_id, name_jp AS name FROM charts
) AS subquery
WHERE name IS NOT NULL AND name <> ''
GROUP BY song_id, name
""",
# endregion
# region INSERT
"""
INSERT INTO properties VALUES ('db_version', '1')
"""
# endregion
],
"update": [],
}
}

View File

@ -1,52 +0,0 @@
from typing import Any, Optional, Sequence
RATING_CLASS_TEXT_MAP = {
0: "Past",
1: "Present",
2: "Future",
3: "Beyond",
}
RATING_CLASS_SHORT_TEXT_MAP = {
0: "PST",
1: "PRS",
2: "FTR",
3: "BYD",
}
def rating_class_to_text(rating_class: int) -> Optional[str]:
return RATING_CLASS_TEXT_MAP.get(rating_class)
def rating_class_to_short_text(rating_class: int) -> Optional[str]:
return RATING_CLASS_SHORT_TEXT_MAP.get(rating_class)
SCORE_GRADE_FLOOR = [9900000, 9800000, 9500000, 9200000, 8900000, 8600000, 0]
SCORE_GRADE_TEXTS = ["EX+", "EX", "AA", "A", "B", "C", "D"]
def zip_score_grade(score: int, __seq: Sequence, default: Any = "__PRESERVE__"):
"""
zip_score_grade is a simple wrapper that equals to:
```py
for score_floor, val in zip(SCORE_GRADE_FLOOR, __seq):
if score >= score_floor:
return val
return seq[-1] if default == "__PRESERVE__" else default
```
Could be useful in specific cases.
"""
return next(
(
val
for score_floor, val in zip(SCORE_GRADE_FLOOR, __seq)
if score >= score_floor
),
__seq[-1] if default == "__PRESERVE__" else default,
)
def score_to_grade_text(score: int) -> str:
return zip_score_grade(score, SCORE_GRADE_TEXTS)

View File

@ -1,12 +0,0 @@
from typing import Generic, TypeVar
T = TypeVar("T")
class Singleton(type, Generic[T]):
_instance = None
def __call__(cls, *args, **kwargs) -> T:
if cls._instance is None:
cls._instance = super().__call__(*args, **kwargs)
return cls._instance

View File

@ -1,8 +0,0 @@
from typing import Any, ClassVar, Dict, Protocol
class TDataclass(Protocol):
__dataclass_fields__: ClassVar[Dict]
def __call__(self, *args: Any, **kwds: Any) -> Any:
...