mirror of
https://github.com/283375/arcaea-offline-pyside-ui.git
synced 2025-07-01 04:16:26 +00:00
wip: arcaea-offline==0.2.0
- fix imports
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
from arcaea_offline.database import Database
|
||||
from arcaea_offline.models import Chart
|
||||
from arcaea_offline.utils import rating_class_to_short_text
|
||||
from arcaea_offline.utils.rating import rating_class_to_short_text
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtGui import QStandardItem, QStandardItemModel
|
||||
|
||||
|
@ -3,7 +3,7 @@ from typing import Any, Callable, Optional, overload
|
||||
|
||||
from arcaea_offline.calculate import calculate_score_range
|
||||
from arcaea_offline.database import Database
|
||||
from arcaea_offline.models import Chart, ScoreInsert
|
||||
from arcaea_offline.models import Chart, Score
|
||||
from arcaea_offline_ocr.b30.shared import B30OcrResultItem
|
||||
from arcaea_offline_ocr.device.shared import DeviceOcrResult
|
||||
from PySide6.QtCore import (
|
||||
@ -47,14 +47,14 @@ class OcrQueueModel(QAbstractListModel):
|
||||
ImagePixmapRole = Qt.ItemDataRole.UserRole + 3
|
||||
|
||||
OcrResultRole = Qt.ItemDataRole.UserRole + 10
|
||||
ScoreInsertRole = Qt.ItemDataRole.UserRole + 11
|
||||
ScoreRole = Qt.ItemDataRole.UserRole + 11
|
||||
ChartRole = Qt.ItemDataRole.UserRole + 12
|
||||
ScoreValidateOkRole = Qt.ItemDataRole.UserRole + 13
|
||||
|
||||
OcrRunnableRole = Qt.ItemDataRole.UserRole + 20
|
||||
ProcessOcrResultFuncRole = (
|
||||
Qt.ItemDataRole.UserRole + 21
|
||||
) # Callable[[imageStr, DeviceOcrResult], tuple[Chart, ScoreInsert]]
|
||||
) # Callable[[imageStr, DeviceOcrResult], tuple[Chart, Score]]
|
||||
|
||||
started = Signal()
|
||||
progress = Signal(int)
|
||||
@ -107,8 +107,8 @@ class OcrQueueModel(QAbstractListModel):
|
||||
self.updateScoreValidateOk(index.row())
|
||||
updateRole = role
|
||||
|
||||
if role == self.ScoreInsertRole and isinstance(value, ScoreInsert):
|
||||
item[self.ScoreInsertRole] = value
|
||||
if role == self.ScoreRole and isinstance(value, Score):
|
||||
item[self.ScoreRole] = value
|
||||
self.updateScoreValidateOk(index.row())
|
||||
updateRole = role
|
||||
|
||||
@ -138,7 +138,7 @@ class OcrQueueModel(QAbstractListModel):
|
||||
self,
|
||||
image: str,
|
||||
runnable: OcrRunnable = None,
|
||||
process_func: Callable[[Optional[str], QImage, Any], ScoreInsert] = None,
|
||||
process_func: Callable[[Optional[str], QImage, Any], Score] = None,
|
||||
):
|
||||
...
|
||||
|
||||
@ -147,7 +147,7 @@ class OcrQueueModel(QAbstractListModel):
|
||||
self,
|
||||
image: QImage,
|
||||
runnable: OcrRunnable = None,
|
||||
process_func: Callable[[Optional[str], QImage, Any], ScoreInsert] = None,
|
||||
process_func: Callable[[Optional[str], QImage, Any], Score] = None,
|
||||
):
|
||||
...
|
||||
|
||||
@ -178,7 +178,7 @@ class OcrQueueModel(QAbstractListModel):
|
||||
self.ImageQImageRole: qImage,
|
||||
self.ImagePixmapRole: qPixmap,
|
||||
self.OcrResultRole: None,
|
||||
self.ScoreInsertRole: None,
|
||||
self.ScoreRole: None,
|
||||
self.ChartRole: None,
|
||||
self.ScoreValidateOkRole: False,
|
||||
self.OcrRunnableRole: runnable,
|
||||
@ -201,7 +201,7 @@ class OcrQueueModel(QAbstractListModel):
|
||||
|
||||
self.setData(index, result, self.OcrResultRole)
|
||||
self.setData(index, chart, self.ChartRole)
|
||||
self.setData(index, scoreInsert, self.ScoreInsertRole)
|
||||
self.setData(index, scoreInsert, self.ScoreRole)
|
||||
return True
|
||||
|
||||
@Slot(DeviceOcrResult)
|
||||
@ -234,8 +234,8 @@ class OcrQueueModel(QAbstractListModel):
|
||||
|
||||
index = self.index(row, 0)
|
||||
chart = index.data(self.ChartRole)
|
||||
score = index.data(self.ScoreInsertRole)
|
||||
if isinstance(chart, Chart) and isinstance(score, ScoreInsert):
|
||||
score = index.data(self.ScoreRole)
|
||||
if isinstance(chart, Chart) and isinstance(score, Score):
|
||||
scoreRange = calculate_score_range(chart, score.pure, score.far)
|
||||
scoreValidateOk = scoreRange[0] <= score.score <= scoreRange[1]
|
||||
self.setData(index, scoreValidateOk, self.ScoreValidateOkRole)
|
||||
@ -247,8 +247,8 @@ class OcrQueueModel(QAbstractListModel):
|
||||
return
|
||||
|
||||
item = self.__items[row]
|
||||
score = item[self.ScoreInsertRole]
|
||||
if not isinstance(score, ScoreInsert) or (
|
||||
score = item[self.ScoreRole]
|
||||
if not isinstance(score, Score) or (
|
||||
not item[self.ScoreValidateOkRole] and not ignoreValidate
|
||||
):
|
||||
return
|
||||
@ -301,7 +301,7 @@ class OcrQueueTableProxyModel(QAbstractTableModel):
|
||||
],
|
||||
[
|
||||
OcrQueueModel.OcrResultRole,
|
||||
OcrQueueModel.ScoreInsertRole,
|
||||
OcrQueueModel.ScoreRole,
|
||||
OcrQueueModel.ChartRole,
|
||||
OcrQueueModel.ScoreValidateOkRole,
|
||||
],
|
||||
@ -364,7 +364,7 @@ class OcrQueueTableProxyModel(QAbstractTableModel):
|
||||
def setData(self, index, value, role):
|
||||
if index.column() == 2 and role == OcrQueueModel.ChartRole:
|
||||
return self.sourceModel().setData(index, value, role)
|
||||
if index.column() == 3 and role == OcrQueueModel.ScoreInsertRole:
|
||||
if index.column() == 3 and role == OcrQueueModel.ScoreRole:
|
||||
return self.sourceModel().setData(index, value, role)
|
||||
return False
|
||||
|
||||
@ -403,8 +403,8 @@ class OcrChartDelegate(ChartDelegate):
|
||||
|
||||
|
||||
class OcrScoreDelegate(ScoreDelegate):
|
||||
def getScoreInsert(self, index: QModelIndex):
|
||||
return index.data(OcrQueueModel.ScoreInsertRole)
|
||||
def getScore(self, index: QModelIndex):
|
||||
return index.data(OcrQueueModel.ScoreRole)
|
||||
|
||||
def getChart(self, index: QModelIndex):
|
||||
return index.data(OcrQueueModel.ChartRole)
|
||||
@ -415,7 +415,7 @@ class OcrScoreDelegate(ScoreDelegate):
|
||||
def paintWarningBackground(self, index: QModelIndex) -> bool:
|
||||
return True
|
||||
# return isinstance(self.getChart(index), Chart) and isinstance(
|
||||
# self.getScore(index), ScoreInsert
|
||||
# self.getScore(index), Score
|
||||
# )
|
||||
# return isinstance(
|
||||
# index.data(OcrQueueModel.OcrResultRole), (DeviceOcrResult, B30OcrResultItem)
|
||||
@ -423,4 +423,4 @@ class OcrScoreDelegate(ScoreDelegate):
|
||||
|
||||
def setModelData(self, editor, model: OcrQueueTableProxyModel, index):
|
||||
if super().confirmSetModelData(editor):
|
||||
model.setData(index, editor.value(), OcrQueueModel.ScoreInsertRole)
|
||||
model.setData(index, editor.value(), OcrQueueModel.ScoreRole)
|
||||
|
11
ui/extends/shared/database.py
Normal file
11
ui/extends/shared/database.py
Normal file
@ -0,0 +1,11 @@
|
||||
from typing import Type
|
||||
|
||||
from PySide6.QtCore import QUrl
|
||||
from sqlalchemy import Engine
|
||||
from sqlalchemy import create_engine as sa_create_engine
|
||||
from sqlalchemy.pool import NullPool, Pool
|
||||
|
||||
|
||||
def create_engine(_url: str | QUrl, pool: Type[Pool] = NullPool) -> Engine:
|
||||
url = _url.toString() if isinstance(_url, QUrl) else _url
|
||||
return sa_create_engine(url, poolclass=pool)
|
@ -1,9 +1,7 @@
|
||||
from typing import Union
|
||||
|
||||
from arcaea_offline.models import Chart
|
||||
from arcaea_offline.utils import rating_class_to_short_text, rating_class_to_text
|
||||
from PySide6.QtCore import QDateTime, QModelIndex, Qt, Signal
|
||||
from PySide6.QtGui import QBrush, QColor
|
||||
from arcaea_offline.utils.rating import rating_class_to_short_text, rating_class_to_text
|
||||
from PySide6.QtCore import QModelIndex, Qt, Signal
|
||||
from PySide6.QtGui import QColor
|
||||
from PySide6.QtWidgets import (
|
||||
QFrame,
|
||||
QHBoxLayout,
|
||||
|
@ -1,16 +1,12 @@
|
||||
from typing import Union
|
||||
|
||||
from arcaea_offline.calculate import calculate_score_range
|
||||
from arcaea_offline.models import Chart, Score, ScoreInsert
|
||||
from arcaea_offline.utils import (
|
||||
rating_class_to_text,
|
||||
score_to_grade_text,
|
||||
zip_score_grade,
|
||||
)
|
||||
from arcaea_offline.models import Chart, Score
|
||||
from arcaea_offline.utils.rating import rating_class_to_text
|
||||
from arcaea_offline.utils.score import score_to_grade_text, zip_score_grade
|
||||
from PySide6.QtCore import QAbstractItemModel, QDateTime, QModelIndex, Qt, Signal
|
||||
from PySide6.QtGui import QColor, QFont, QLinearGradient
|
||||
from PySide6.QtWidgets import (
|
||||
QAbstractItemDelegate,
|
||||
QFrame,
|
||||
QHBoxLayout,
|
||||
QLabel,
|
||||
@ -53,7 +49,7 @@ class ScoreEditorDelegateWrapper(ScoreEditor):
|
||||
|
||||
self.formLayout.insertRow(0, self.delegateHeader)
|
||||
|
||||
def setText(self, score: Score | ScoreInsert, _extra: str = None):
|
||||
def setText(self, score: Score, _extra: str = None):
|
||||
text = "Editing "
|
||||
text += _extra or ""
|
||||
text += f"score {score.score}"
|
||||
@ -91,22 +87,14 @@ class ScoreDelegate(TextSegmentDelegate):
|
||||
def getScore(self, index: QModelIndex) -> Score | None:
|
||||
return None
|
||||
|
||||
def getScoreInsert(self, index: QModelIndex) -> ScoreInsert | None:
|
||||
return None
|
||||
|
||||
def _getScore(self, index: QModelIndex):
|
||||
score = self.getScore(index)
|
||||
scoreInsert = self.getScoreInsert(index)
|
||||
return scoreInsert if score is None else score
|
||||
|
||||
def getChart(self, index: QModelIndex) -> Chart | None:
|
||||
return None
|
||||
|
||||
def getScoreValidateOk(self, index: QModelIndex) -> bool | None:
|
||||
score = self._getScore(index)
|
||||
score = self.getScore(index)
|
||||
chart = self.getChart(index)
|
||||
|
||||
if isinstance(score, (Score, ScoreInsert)) and isinstance(chart, Chart):
|
||||
if isinstance(score, Score) and isinstance(chart, Chart):
|
||||
scoreRange = calculate_score_range(chart, score.pure, score.far)
|
||||
return scoreRange[0] <= score.score <= scoreRange[1]
|
||||
|
||||
@ -114,9 +102,9 @@ class ScoreDelegate(TextSegmentDelegate):
|
||||
return zip_score_grade(score, self.GradeGradientsWrappers)
|
||||
|
||||
def getTextSegments(self, index, option):
|
||||
score = self._getScore(index)
|
||||
score = self.getScore(index)
|
||||
chart = self.getChart(index)
|
||||
if not (isinstance(score, (Score, ScoreInsert)) and isinstance(chart, Chart)):
|
||||
if not (isinstance(score, Score) and isinstance(chart, Chart)):
|
||||
return [
|
||||
[
|
||||
{
|
||||
@ -176,10 +164,10 @@ class ScoreDelegate(TextSegmentDelegate):
|
||||
|
||||
def paint(self, painter, option, index):
|
||||
# draw scoreMismatch warning background
|
||||
score = self._getScore(index)
|
||||
score = self.getScore(index)
|
||||
chart = self.getChart(index)
|
||||
if (
|
||||
isinstance(score, (Score, ScoreInsert))
|
||||
isinstance(score, Score)
|
||||
and isinstance(chart, Chart)
|
||||
and self.paintWarningBackground(index)
|
||||
):
|
||||
@ -206,16 +194,16 @@ class ScoreDelegate(TextSegmentDelegate):
|
||||
self.closeEditor.emit(editor)
|
||||
|
||||
def createEditor(self, parent, option, index) -> ScoreEditorDelegateWrapper:
|
||||
score = self._getScore(index)
|
||||
score = self.getScore(index)
|
||||
chart = self.getChart(index)
|
||||
if isinstance(score, (Score, ScoreInsert)) and isinstance(chart, Chart):
|
||||
if isinstance(score, Score) and isinstance(chart, Chart):
|
||||
editor = ScoreEditorDelegateWrapper(parent)
|
||||
editor.setWindowFlag(Qt.WindowType.Sheet, True)
|
||||
editor.setWindowFlag(Qt.WindowType.FramelessWindowHint, True)
|
||||
editor.setWindowTitle(
|
||||
f"{chart.name_en}({chart.song_id}) | {rating_class_to_text(chart.rating_class)} | {chart.package_id}"
|
||||
)
|
||||
editor.setText(self._getScore(index))
|
||||
editor.setText(self.getScore(index))
|
||||
editor.setValidateBeforeAccept(False)
|
||||
editor.move(parent.mapToGlobal(parent.pos()))
|
||||
editor.accepted.connect(self._commitEditor)
|
||||
@ -231,9 +219,9 @@ class ScoreDelegate(TextSegmentDelegate):
|
||||
keepWidgetInScreen(editor)
|
||||
|
||||
def setEditorData(self, editor: ScoreEditorDelegateWrapper, index) -> None:
|
||||
score = self._getScore(index)
|
||||
score = self.getScore(index)
|
||||
chart = self.getChart(index)
|
||||
if isinstance(score, (Score, ScoreInsert)) and isinstance(chart, Chart):
|
||||
if isinstance(score, Score) and isinstance(chart, Chart):
|
||||
editor.setChart(chart)
|
||||
editor.setValue(score)
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
from arcaea_offline.calculate import calculate_score
|
||||
from arcaea_offline.models import Chart, Score, ScoreInsert
|
||||
# from arcaea_offline.calculate import calculate_score
|
||||
from arcaea_offline.models import Chart, Score
|
||||
from PySide6.QtCore import QCoreApplication, QModelIndex, QSortFilterProxyModel, Qt
|
||||
|
||||
from .base import DbTableModel
|
||||
|
@ -1,7 +1,7 @@
|
||||
from PySide6.QtCore import QDir, QSettings
|
||||
from PySide6.QtCore import QDir, QSettings, QUrl
|
||||
|
||||
__all__ = [
|
||||
"DATABASE_PATH",
|
||||
"DATABASE_URL",
|
||||
"DEVICES_JSON_FILE",
|
||||
"DEVICE_UUID",
|
||||
"TESSERACT_FILE",
|
||||
@ -10,7 +10,7 @@ __all__ = [
|
||||
"Settings",
|
||||
]
|
||||
|
||||
DATABASE_PATH = "General/DatabasePath"
|
||||
DATABASE_URL = "General/DatabaseUrl"
|
||||
|
||||
DEVICES_JSON_FILE = "Ocr/DevicesJsonFile"
|
||||
DEVICE_UUID = "Ocr/DeviceUuid"
|
||||
@ -27,6 +27,13 @@ class Settings(QSettings):
|
||||
parent,
|
||||
)
|
||||
|
||||
def databaseUrl(self) -> str | None:
|
||||
return self.value(DATABASE_URL, None, str)
|
||||
|
||||
def setDatabaseUrl(self, value: str):
|
||||
self.setValue(DATABASE_URL, value)
|
||||
self.sync()
|
||||
|
||||
def devicesJsonFile(self) -> str | None:
|
||||
return self.value(DEVICES_JSON_FILE, None, str)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import logging
|
||||
|
||||
from arcaea_offline.database import Database
|
||||
from arcaea_offline.models import Chart, ScoreInsert
|
||||
from arcaea_offline.models import Chart, Score
|
||||
from arcaea_offline_ocr.b30.chieri.v4.ocr import ChieriBotV4Ocr
|
||||
from arcaea_offline_ocr.b30.shared import B30OcrResultItem
|
||||
from PySide6.QtGui import QImage
|
||||
|
@ -3,7 +3,7 @@ import logging
|
||||
from typing import Tuple
|
||||
|
||||
from arcaea_offline.database import Database
|
||||
from arcaea_offline.models import Chart, ScoreInsert
|
||||
from arcaea_offline.models import Chart, Score
|
||||
from arcaea_offline_ocr.device.shared import DeviceOcrResult
|
||||
from arcaea_offline_ocr.device.v2.ocr import DeviceV2Ocr
|
||||
from arcaea_offline_ocr.device.v2.rois import DeviceV2Rois
|
||||
@ -52,9 +52,7 @@ def getImageDate(imagePath: str) -> QDateTime:
|
||||
|
||||
class ScoreInsertConverter:
|
||||
@staticmethod
|
||||
def deviceV2(
|
||||
imagePath: str, _, result: DeviceOcrResult
|
||||
) -> Tuple[Chart, ScoreInsert]:
|
||||
def deviceV2(imagePath: str, _, result: DeviceOcrResult) -> Tuple[Chart, Score]:
|
||||
db = Database()
|
||||
scoreInsert = ScoreInsert(
|
||||
song_id=result.song_id,
|
||||
|
Reference in New Issue
Block a user