6 Commits

Author SHA1 Message Date
64285c350c ci: dist file discovery 2024-04-01 00:10:30 +08:00
62c3431cff chore: v0.2.2 2024-03-31 23:56:18 +08:00
280543660a ci: build package using github actions 2024-03-31 23:54:58 +08:00
8dc433b12a feat: ETERNAL rating class support 2024-03-20 15:52:55 +08:00
2bd64bbd5e feat(external): supporting chart info database 2024-03-16 01:54:26 +08:00
54749c8df2 feat(db): DEF v2 scores export supporting 2024-02-27 17:23:43 +08:00
9 changed files with 147 additions and 5 deletions

View File

@ -0,0 +1,48 @@
name: "Build and draft a release"
on:
workflow_dispatch:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
permissions:
contents: write
discussions: write
jobs:
build-and-draft-release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python environment
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Build package
run: |
pip install build
python -m build
- name: Remove `v` in tag name
uses: mad9000/actions-find-and-replace-string@5
id: tagNameReplaced
with:
source: ${{ github.ref_name }}
find: "v"
replace: ""
- name: Draft a release
uses: softprops/action-gh-release@v2
with:
discussion_category_name: New releases
draft: true
generate_release_notes: true
files: |
dist/arcaea_offline-${{ steps.tagNameReplaced.outputs.value }}*.whl
dist/arcaea-offline-${{ steps.tagNameReplaced.outputs.value }}.tar.gz

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "arcaea-offline"
version = "0.2.1"
version = "0.2.2"
authors = [{ name = "283375", email = "log_283375@163.com" }]
description = "Manage your local Arcaea score database."
readme = "README.md"

View File

@ -6,7 +6,7 @@ from sqlalchemy import Engine, func, inspect, select
from sqlalchemy.orm import DeclarativeBase, InstrumentedAttribute, sessionmaker
from .external.arcsong.arcsong_json import ArcSongJsonBuilder
from .external.exports import ScoreExport, exporters
from .external.exports import ArcaeaOfflineDEFV2_Score, ScoreExport, exporters
from .models.config import ConfigBase, Property
from .models.scores import (
CalculatedPotential,
@ -410,6 +410,15 @@ class Database(metaclass=Singleton):
scores = self.get_scores()
return [exporters.score(score) for score in scores]
def export_scores_def_v2(self) -> ArcaeaOfflineDEFV2_Score:
scores = self.get_scores()
return {
"$schema": "https://arcaeaoffline.sevive.xyz/schemas/def/v2/score.schema.json",
"type": "score",
"version": 2,
"scores": [exporters.score_def_v2(score) for score in scores],
}
def generate_arcsong(self):
with self.sessionmaker() as session:
arcsong = ArcSongJsonBuilder(session).generate_arcsong_json()

View File

@ -0,0 +1 @@
from .parser import ChartInfoDbParser

View File

@ -0,0 +1,35 @@
import contextlib
import sqlite3
from typing import List
from sqlalchemy.orm import Session
from ...models.songs import ChartInfo
class ChartInfoDbParser:
def __init__(self, filepath):
self.filepath = filepath
def parse(self) -> List[ChartInfo]:
results = []
with sqlite3.connect(self.filepath) as conn:
with contextlib.closing(conn.cursor()) as cursor:
db_results = cursor.execute(
"SELECT song_id, rating_class, constant, notes FROM charts_info"
).fetchall()
for result in db_results:
chart = ChartInfo(
song_id=result[0],
rating_class=result[1],
constant=result[2],
notes=result[3] or None,
)
results.append(chart)
return results
def write_database(self, session: Session):
results = self.parse()
for result in results:
session.merge(result)

View File

@ -1,2 +1,2 @@
from . import exporters
from .types import ScoreExport
from .types import ArcaeaOfflineDEFV2_Score, ScoreExport

View File

@ -1,5 +1,5 @@
from ...models import Score
from .types import ScoreExport
from .types import ArcaeaOfflineDEFV2_ScoreItem, ScoreExport
def score(score: Score) -> ScoreExport:
@ -17,3 +17,21 @@ def score(score: Score) -> ScoreExport:
"clear_type": score.clear_type,
"comment": score.comment,
}
def score_def_v2(score: Score) -> ArcaeaOfflineDEFV2_ScoreItem:
return {
"id": score.id,
"songId": score.song_id,
"ratingClass": score.rating_class,
"score": score.score,
"pure": score.pure,
"far": score.far,
"lost": score.lost,
"date": score.date,
"maxRecall": score.max_recall,
"modifier": score.modifier,
"clearType": score.clear_type,
"source": None,
"comment": score.comment,
}

View File

@ -1,4 +1,4 @@
from typing import Optional, TypedDict
from typing import List, Literal, Optional, TypedDict
class ScoreExport(TypedDict):
@ -14,3 +14,32 @@ class ScoreExport(TypedDict):
modifier: Optional[int]
clear_type: Optional[int]
comment: Optional[str]
class ArcaeaOfflineDEFV2_ScoreItem(TypedDict, total=False):
id: Optional[int]
songId: str
ratingClass: int
score: int
pure: Optional[int]
far: Optional[int]
lost: Optional[int]
date: Optional[int]
maxRecall: Optional[int]
modifier: Optional[int]
clearType: Optional[int]
source: Optional[str]
comment: Optional[str]
ArcaeaOfflineDEFV2_Score = TypedDict(
"ArcaeaOfflineDEFV2_Score",
{
"$schema": Literal[
"https://arcaeaoffline.sevive.xyz/schemas/def/v2/score.schema.json"
],
"type": Literal["score"],
"version": Literal[2],
"scores": List[ArcaeaOfflineDEFV2_ScoreItem],
},
)

View File

@ -5,6 +5,7 @@ RATING_CLASS_TEXT_MAP = {
1: "Present",
2: "Future",
3: "Beyond",
4: "Eternal",
}
RATING_CLASS_SHORT_TEXT_MAP = {
@ -12,6 +13,7 @@ RATING_CLASS_SHORT_TEXT_MAP = {
1: "PRS",
2: "FTR",
3: "BYD",
4: "ETR",
}