feat(beatmap,score): update beatmaps from Bancho & deleting scores (#50)

New API:

- DELETE /api/private/score/{score_id}: delete a score
- POST /api/private/beatmapsets/{beatmapset_id}/sync: request for syncing a beatmapset

New configuration:

- OLD_SCORE_PROCESSING_MODE
This commit is contained in:
MingxuanGame
2025-10-02 13:36:09 +08:00
committed by GitHub
parent 860ebe9fa9
commit 3f6776847e
22 changed files with 888 additions and 84 deletions

View File

@@ -0,0 +1,61 @@
"""score: save ranked into database
Revision ID: dc2087561edf
Revises: 9419272e4c85
Create Date: 2025-09-30 10:44:25.286498
"""
from __future__ import annotations
from collections.abc import Sequence
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = "dc2087561edf"
down_revision: str | Sequence[str] | None = "9419272e4c85"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("scores", sa.Column("ranked", sa.Boolean(), nullable=True))
op.execute("UPDATE scores SET ranked = pp > 0")
op.alter_column("scores", "ranked", nullable=False, type_=sa.Boolean(), existing_type=sa.Boolean())
op.drop_constraint(op.f("best_scores_ibfk_2"), "best_scores", type_="foreignkey")
op.create_foreign_key(op.f("best_scores_ibfk_2"), "best_scores", "scores", ["score_id"], ["id"], ondelete="CASCADE")
op.drop_constraint(op.f("playlist_best_scores_ibfk_3"), "playlist_best_scores", type_="foreignkey")
op.create_foreign_key(
op.f("playlist_best_scores_ibfk_3"), "playlist_best_scores", "scores", ["score_id"], ["id"], ondelete="CASCADE"
)
op.drop_constraint(op.f("total_score_best_scores_ibfk_2"), "total_score_best_scores", type_="foreignkey")
op.create_foreign_key(
op.f("total_score_best_scores_ibfk_2"),
"total_score_best_scores",
"scores",
["score_id"],
["id"],
ondelete="CASCADE",
)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("scores", "ranked")
op.drop_constraint(op.f("best_scores_ibfk_2"), "best_scores", type_="foreignkey")
op.create_foreign_key(op.f("best_scores_ibfk_2"), "best_scores", "scores", ["score_id"], ["id"])
op.drop_constraint(op.f("playlist_best_scores_ibfk_3"), "playlist_best_scores", type_="foreignkey")
op.create_foreign_key(op.f("playlist_best_scores_ibfk_3"), "playlist_best_scores", "scores", ["score_id"], ["id"])
op.drop_constraint(op.f("total_score_best_scores_ibfk_2"), "total_score_best_scores", type_="foreignkey")
op.create_foreign_key(
op.f("total_score_best_scores_ibfk_2"), "total_score_best_scores", "scores", ["score_id"], ["id"]
)
# ### end Alembic commands ###

View File

@@ -0,0 +1,54 @@
"""sync: add beatmap sync table
Revision ID: 2885978490dc
Revises: dc2087561edf
Create Date: 2025-10-01 12:19:50.485318
"""
from __future__ import annotations
from collections.abc import Sequence
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = "2885978490dc"
down_revision: str | Sequence[str] | None = "dc2087561edf"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
"""Upgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"beatmapsync",
sa.Column("beatmapset_id", sa.Integer(), nullable=False),
sa.Column("beatmaps", sa.JSON(), nullable=True),
sa.Column(
"beatmap_status",
sa.Enum(
"GRAVEYARD", "WIP", "PENDING", "RANKED", "APPROVED", "QUALIFIED", "LOVED", name="beatmaprankstatus"
),
nullable=False,
),
sa.Column("consecutive_no_change", sa.Integer(), nullable=False),
sa.Column("next_sync_time", sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(
["beatmapset_id"],
["beatmapsets.id"],
),
sa.PrimaryKeyConstraint("beatmapset_id"),
)
op.create_index(op.f("ix_beatmapsync_beatmap_status"), "beatmapsync", ["beatmap_status"], unique=False)
op.create_index(op.f("ix_beatmapsync_next_sync_time"), "beatmapsync", ["next_sync_time"], unique=False)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("beatmapsync")
# ### end Alembic commands ###

View File

@@ -0,0 +1,35 @@
"""sync: add updated_at
Revision ID: b1ac2154bd0d
Revises: 2885978490dc
Create Date: 2025-10-01 14:56:08.539694
"""
from __future__ import annotations
from collections.abc import Sequence
from alembic import op
import sqlalchemy as sa
import sqlmodel
# revision identifiers, used by Alembic.
revision: str = "b1ac2154bd0d"
down_revision: str | Sequence[str] | None = "2885978490dc"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
"""Upgrade schema."""
op.add_column("beatmapsync", sa.Column("updated_at", sa.DateTime(), nullable=True))
op.execute(sqlmodel.text("UPDATE beatmapsync SET updated_at = NOW() WHERE updated_at IS NULL"))
op.alter_column("beatmapsync", "updated_at", nullable=False, type_=sa.DateTime())
op.create_index(op.f("ix_beatmapsync_updated_at"), "beatmapsync", ["updated_at"], unique=False)
def downgrade() -> None:
"""Downgrade schema."""
op.drop_index(op.f("ix_beatmapsync_updated_at"), table_name="beatmapsync")
op.drop_column("beatmapsync", "updated_at")