mirror of
https://github.com/283375/arcaea-offline-pyside-ui.git
synced 2025-04-20 17:50:17 +00:00
wip: arcaea-offline==0.2.0
- fix viewing/database read references of `ScoreInsert`
This commit is contained in:
parent
accf547e90
commit
a9d2b5f75d
@ -236,7 +236,7 @@ class OcrQueueModel(QAbstractListModel):
|
|||||||
chart = index.data(self.ChartRole)
|
chart = index.data(self.ChartRole)
|
||||||
score = index.data(self.ScoreRole)
|
score = index.data(self.ScoreRole)
|
||||||
if isinstance(chart, Chart) and isinstance(score, Score):
|
if isinstance(chart, Chart) and isinstance(score, Score):
|
||||||
scoreRange = calculate_score_range(chart, score.pure, score.far)
|
scoreRange = calculate_score_range(chart.note, score.pure, score.far)
|
||||||
scoreValidateOk = scoreRange[0] <= score.score <= scoreRange[1]
|
scoreValidateOk = scoreRange[0] <= score.score <= scoreRange[1]
|
||||||
self.setData(index, scoreValidateOk, self.ScoreValidateOkRole)
|
self.setData(index, scoreValidateOk, self.ScoreValidateOkRole)
|
||||||
else:
|
else:
|
||||||
|
@ -20,9 +20,9 @@ from .base import TextSegmentDelegate
|
|||||||
|
|
||||||
def chartToRichText(chart: Chart):
|
def chartToRichText(chart: Chart):
|
||||||
if isinstance(chart, Chart):
|
if isinstance(chart, Chart):
|
||||||
text = f"{chart.name_en} [{rating_class_to_short_text(chart.rating_class)}]"
|
text = f"{chart.title} [{rating_class_to_short_text(chart.rating_class)}]"
|
||||||
text += "<br>"
|
text += "<br>"
|
||||||
text += f'<font color="gray">({chart.song_id}, {chart.package_id})</font>'
|
text += f'<font color="gray">({chart.song_id}, {chart.set})</font>'
|
||||||
else:
|
else:
|
||||||
text = "(unknown chart)"
|
text = "(unknown chart)"
|
||||||
return text
|
return text
|
||||||
@ -94,7 +94,7 @@ class ChartDelegate(TextSegmentDelegate):
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
{self.TextRole: f"{chart.name_en}"},
|
{self.TextRole: f"{chart.title}"},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -104,7 +104,7 @@ class ChartDelegate(TextSegmentDelegate):
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
self.TextRole: f"({chart.song_id}, {chart.package_id})",
|
self.TextRole: f"({chart.song_id}, {chart.set})",
|
||||||
self.ColorRole: option.widget.palette().placeholderText().color(),
|
self.ColorRole: option.widget.palette().placeholderText().color(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -95,7 +95,7 @@ class ScoreDelegate(TextSegmentDelegate):
|
|||||||
chart = self.getChart(index)
|
chart = self.getChart(index)
|
||||||
|
|
||||||
if isinstance(score, Score) and isinstance(chart, Chart):
|
if isinstance(score, Score) and isinstance(chart, Chart):
|
||||||
scoreRange = calculate_score_range(chart, score.pure, score.far)
|
scoreRange = calculate_score_range(chart.note, score.pure, score.far)
|
||||||
return scoreRange[0] <= score.score <= scoreRange[1]
|
return scoreRange[0] <= score.score <= scoreRange[1]
|
||||||
|
|
||||||
def getScoreGradeGradientWrapper(self, score: int):
|
def getScoreGradeGradientWrapper(self, score: int):
|
||||||
@ -152,9 +152,11 @@ class ScoreDelegate(TextSegmentDelegate):
|
|||||||
],
|
],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
self.TextRole: QDateTime.fromSecsSinceEpoch(score.time).toString(
|
self.TextRole: QDateTime.fromSecsSinceEpoch(score.date).toString(
|
||||||
"yyyy-MM-dd hh:mm:ss"
|
"yyyy-MM-dd hh:mm:ss"
|
||||||
)
|
)
|
||||||
|
if score.date
|
||||||
|
else "-- No Date --"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from arcaea_offline.models import Chart, Score
|
from arcaea_offline.models import Chart, Score, ScoreBest
|
||||||
from PySide6.QtCore import QCoreApplication, QModelIndex, QSortFilterProxyModel, Qt
|
from PySide6.QtCore import QCoreApplication, QModelIndex, QSortFilterProxyModel, Qt
|
||||||
|
from sqlalchemy import select
|
||||||
|
|
||||||
from .base import DbTableModel
|
from .base import DbTableModel
|
||||||
|
|
||||||
@ -27,18 +28,19 @@ class DbB30TableModel(DbTableModel):
|
|||||||
def syncDb(self):
|
def syncDb(self):
|
||||||
self.__items.clear()
|
self.__items.clear()
|
||||||
|
|
||||||
results = self._db.conn.execute(
|
with self._db.sessionmaker() as session:
|
||||||
'SELECT * FROM calculated GROUP BY "potential" ORDER BY "potential" DESC LIMIT 40'
|
results = list(
|
||||||
).fetchall()
|
session.scalars(
|
||||||
|
select(ScoreBest).order_by(ScoreBest.potential.desc()).limit(40)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
songIds = [r[0] for r in results]
|
songIds = [r.id for r in results]
|
||||||
ptts = [r[-1] for r in results]
|
ptts = [r.potential for r in results]
|
||||||
|
|
||||||
for scoreId, ptt in zip(songIds, ptts):
|
for scoreId, ptt in zip(songIds, ptts):
|
||||||
score = Score.from_db_row(self._db.get_scores(score_id=scoreId)[0])
|
score = self._db.get_score_by_id(scoreId)
|
||||||
chart = Chart.from_db_row(
|
chart = self._db.get_chart(score.song_id, score.rating_class)
|
||||||
self._db.get_chart(score.song_id, score.rating_class)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
|
self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
|
||||||
self.__items.append(
|
self.__items.append(
|
||||||
@ -131,7 +133,12 @@ class DbB30TableSortFilterProxyModel(QSortFilterProxyModel):
|
|||||||
if self.sortRole() == self.Sort_C2_ScoreRole:
|
if self.sortRole() == self.Sort_C2_ScoreRole:
|
||||||
return score_left.score < score_right.score
|
return score_left.score < score_right.score
|
||||||
elif self.sortRole() == self.Sort_C2_TimeRole:
|
elif self.sortRole() == self.Sort_C2_TimeRole:
|
||||||
return score_left.time < score_right.time
|
if score_left.date and score_right.date:
|
||||||
|
return score_left.date < score_right.date
|
||||||
|
elif score_left.date:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
elif column == 3:
|
elif column == 3:
|
||||||
return source_left.data(DbB30TableModel.PttRole) < source_right.data(
|
return source_left.data(DbB30TableModel.PttRole) < source_right.data(
|
||||||
DbB30TableModel.PttRole
|
DbB30TableModel.PttRole
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# from arcaea_offline.calculate import calculate_score
|
from arcaea_offline.calculate import calculate_potential
|
||||||
from arcaea_offline.models import Chart, Score
|
from arcaea_offline.models import Chart, Score
|
||||||
from PySide6.QtCore import QCoreApplication, QModelIndex, QSortFilterProxyModel, Qt
|
from PySide6.QtCore import QCoreApplication, QModelIndex, QSortFilterProxyModel, Qt
|
||||||
|
|
||||||
@ -27,19 +27,15 @@ class DbScoreTableModel(DbTableModel):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def syncDb(self):
|
def syncDb(self):
|
||||||
newScores = [Score.from_db_row(dbRow) for dbRow in self._db.get_scores()]
|
newScores = self._db.get_scores()
|
||||||
newScores = sorted(newScores, key=lambda x: x.id)
|
newScores = sorted(newScores, key=lambda x: x.id)
|
||||||
newCharts = [
|
newCharts = [
|
||||||
Chart.from_db_row(dbRow)
|
self._db.get_chart(score.song_id, score.rating_class) for score in newScores
|
||||||
for dbRow in [
|
|
||||||
self._db.get_chart(score.song_id, score.rating_class)
|
|
||||||
for score in newScores
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
newPtts = []
|
newPtts = []
|
||||||
for chart, score in zip(newCharts, newScores):
|
for chart, score in zip(newCharts, newScores):
|
||||||
if isinstance(chart, Chart) and isinstance(score, Score):
|
if isinstance(chart, Chart) and isinstance(score, Score):
|
||||||
newPtts.append(calculate_score(chart, score).potential)
|
newPtts.append(calculate_potential(chart.constant / 10, score.score))
|
||||||
else:
|
else:
|
||||||
newPtts.append(None)
|
newPtts.append(None)
|
||||||
|
|
||||||
@ -117,11 +113,7 @@ class DbScoreTableModel(DbTableModel):
|
|||||||
if not (index.isValid() and self.checkIndex(index)):
|
if not (index.isValid() and self.checkIndex(index)):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if (
|
if index.column() == 2 and isinstance(value, Score) and role == self.ScoreRole:
|
||||||
index.column() == 2
|
|
||||||
and isinstance(value, ScoreInsert)
|
|
||||||
and role == self.ScoreRole
|
|
||||||
):
|
|
||||||
self._db.update_score(self.__items[index.row()][self.IdRole], value)
|
self._db.update_score(self.__items[index.row()][self.IdRole], value)
|
||||||
self.syncDb()
|
self.syncDb()
|
||||||
return True
|
return True
|
||||||
@ -189,7 +181,12 @@ class DbScoreTableSortFilterProxyModel(QSortFilterProxyModel):
|
|||||||
if self.sortRole() == self.Sort_C2_ScoreRole:
|
if self.sortRole() == self.Sort_C2_ScoreRole:
|
||||||
return score_left.score < score_right.score
|
return score_left.score < score_right.score
|
||||||
elif self.sortRole() == self.Sort_C2_TimeRole:
|
elif self.sortRole() == self.Sort_C2_TimeRole:
|
||||||
return score_left.time < score_right.time
|
if score_left.date and score_right.date:
|
||||||
|
return score_left.date < score_right.date
|
||||||
|
elif score_left.date:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
elif column == 3:
|
elif column == 3:
|
||||||
return source_left.data(DbScoreTableModel.PttRole) < source_right.data(
|
return source_left.data(DbScoreTableModel.PttRole) < source_right.data(
|
||||||
DbScoreTableModel.PttRole
|
DbScoreTableModel.PttRole
|
||||||
|
@ -50,22 +50,22 @@ def getImageDate(imagePath: str) -> QDateTime:
|
|||||||
return datetime
|
return datetime
|
||||||
|
|
||||||
|
|
||||||
class ScoreInsertConverter:
|
class ScoreConverter:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def deviceV2(imagePath: str, _, result: DeviceOcrResult) -> Tuple[Chart, Score]:
|
def deviceV2(imagePath: str, _, result: DeviceOcrResult) -> Tuple[Chart, Score]:
|
||||||
db = Database()
|
db = Database()
|
||||||
scoreInsert = ScoreInsert(
|
score = Score(
|
||||||
song_id=result.song_id,
|
song_id=result.song_id,
|
||||||
rating_class=result.rating_class,
|
rating_class=result.rating_class,
|
||||||
score=result.score,
|
score=result.score,
|
||||||
pure=result.pure,
|
pure=result.pure,
|
||||||
far=result.far,
|
far=result.far,
|
||||||
lost=result.lost,
|
lost=result.lost,
|
||||||
time=getImageDate(imagePath).toSecsSinceEpoch(),
|
date=getImageDate(imagePath).toSecsSinceEpoch(),
|
||||||
max_recall=result.max_recall,
|
max_recall=result.max_recall,
|
||||||
clear_type=None,
|
r10_clear_type=None,
|
||||||
|
comment=f"OCR {QFileInfo(imagePath).fileName()}",
|
||||||
)
|
)
|
||||||
chart = Chart.from_db_row(
|
print(f"OCR {QFileInfo(imagePath).fileName()}")
|
||||||
db.get_chart(scoreInsert.song_id, scoreInsert.rating_class)
|
chart = db.get_chart(score.song_id, score.rating_class)
|
||||||
)
|
return (chart, score)
|
||||||
return (chart, scoreInsert)
|
|
||||||
|
@ -132,7 +132,7 @@ class ScoreEditor(Ui_ScoreEditor, QWidget):
|
|||||||
|
|
||||||
score = self.value()
|
score = self.value()
|
||||||
|
|
||||||
score_range = calculate_score_range(self.__chart, score.pure, score.far)
|
score_range = calculate_score_range(self.__chart.note, score.pure, score.far)
|
||||||
score_in_range = score_range[0] <= score.score <= score_range[1]
|
score_in_range = score_range[0] <= score.score <= score_range[1]
|
||||||
note_in_range = score.pure + score.far + score.lost <= self.__chart.note
|
note_in_range = score.pure + score.far + score.lost <= self.__chart.note
|
||||||
if not score_in_range or not note_in_range:
|
if not score_in_range or not note_in_range:
|
||||||
|
@ -12,10 +12,7 @@ from PySide6.QtWidgets import QFileDialog, QWidget
|
|||||||
from ui.designer.tabs.tabOcr.tabOcr_Device_ui import Ui_TabOcr_Device
|
from ui.designer.tabs.tabOcr.tabOcr_Device_ui import Ui_TabOcr_Device
|
||||||
from ui.extends.components.ocrQueue import OcrQueueModel
|
from ui.extends.components.ocrQueue import OcrQueueModel
|
||||||
from ui.extends.shared.settings import Settings
|
from ui.extends.shared.settings import Settings
|
||||||
from ui.extends.tabs.tabOcr.tabOcr_Device import (
|
from ui.extends.tabs.tabOcr.tabOcr_Device import ScoreConverter, TabDeviceV2OcrRunnable
|
||||||
ScoreInsertConverter,
|
|
||||||
TabDeviceV2OcrRunnable,
|
|
||||||
)
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -104,7 +101,7 @@ class TabOcr_Device(Ui_TabOcr_Device, QWidget):
|
|||||||
self.ocrQueueModel.setData(index, runnable, OcrQueueModel.OcrRunnableRole)
|
self.ocrQueueModel.setData(index, runnable, OcrQueueModel.OcrRunnableRole)
|
||||||
self.ocrQueueModel.setData(
|
self.ocrQueueModel.setData(
|
||||||
index,
|
index,
|
||||||
ScoreInsertConverter.deviceV2,
|
ScoreConverter.deviceV2,
|
||||||
OcrQueueModel.ProcessOcrResultFuncRole,
|
OcrQueueModel.ProcessOcrResultFuncRole,
|
||||||
)
|
)
|
||||||
self.ocrQueueModel.startQueue()
|
self.ocrQueueModel.startQueue()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user