draftomen 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- draftomen/__init__.py +17 -0
- draftomen/assets/draftomen.icns +0 -0
- draftomen/assets/draftomen.ico +0 -0
- draftomen/assets/draftomen_logo.png +0 -0
- draftomen/audit.py +606 -0
- draftomen/backtest.py +449 -0
- draftomen/benchmark.py +834 -0
- draftomen/carddb.py +1869 -0
- draftomen/cardimages.py +313 -0
- draftomen/cli.py +891 -0
- draftomen/config.py +133 -0
- draftomen/deckbuilder.py +2723 -0
- draftomen/events.py +772 -0
- draftomen/logfollow.py +451 -0
- draftomen/mock_session.py +745 -0
- draftomen/paths.py +120 -0
- draftomen/pickengine.py +1117 -0
- draftomen/pool.py +1259 -0
- draftomen/preferences.py +289 -0
- draftomen/qml/AboutDialog.qml +156 -0
- draftomen/qml/AppBar.qml +120 -0
- draftomen/qml/BacktestView.qml +316 -0
- draftomen/qml/BuildView.qml +1151 -0
- draftomen/qml/CardPreview.qml +434 -0
- draftomen/qml/DimensionalButton.qml +42 -0
- draftomen/qml/DimensionalComboBox.qml +182 -0
- draftomen/qml/DimensionalSurface.qml +118 -0
- draftomen/qml/DimensionalTabButton.qml +41 -0
- draftomen/qml/LiveDraftView.qml +468 -0
- draftomen/qml/Main.qml +175 -0
- draftomen/qml/NavigationRail.qml +226 -0
- draftomen/qml/PoolSummaryPanel.qml +322 -0
- draftomen/qml/PrivacyDialog.qml +96 -0
- draftomen/qml/RecentPickThumbnail.qml +83 -0
- draftomen/qml/RecentPicksGallery.qml +333 -0
- draftomen/qml/RecommendationRow.qml +404 -0
- draftomen/qml/SettingsSwitch.qml +141 -0
- draftomen/qml/SettingsView.qml +531 -0
- draftomen/qml/StateBanner.qml +189 -0
- draftomen/qml/StatusStrip.qml +84 -0
- draftomen/qml/Theme.qml +71 -0
- draftomen/qml/qmldir +23 -0
- draftomen/qt_adapter.py +884 -0
- draftomen/qt_gui.py +338 -0
- draftomen/qt_mock.py +63 -0
- draftomen/ranking.py +126 -0
- draftomen/replay.py +480 -0
- draftomen/session.py +3668 -0
- draftomen/setinfo.py +26 -0
- draftomen/seventeen.py +2766 -0
- draftomen/splash.py +617 -0
- draftomen/tui.py +4007 -0
- draftomen/watch.py +336 -0
- draftomen-0.3.0.dist-info/METADATA +156 -0
- draftomen-0.3.0.dist-info/RECORD +59 -0
- draftomen-0.3.0.dist-info/WHEEL +5 -0
- draftomen-0.3.0.dist-info/entry_points.txt +6 -0
- draftomen-0.3.0.dist-info/licenses/LICENSE +21 -0
- draftomen-0.3.0.dist-info/top_level.txt +1 -0
draftomen/qml/Main.qml
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import QtQuick 2.15
|
|
2
|
+
import QtQuick.Controls 2.15
|
|
3
|
+
import QtQuick.Layouts 1.15
|
|
4
|
+
|
|
5
|
+
ApplicationWindow {
|
|
6
|
+
id: window
|
|
7
|
+
required property var provider
|
|
8
|
+
|
|
9
|
+
width: initialWindowWidth
|
|
10
|
+
height: initialWindowHeight
|
|
11
|
+
minimumWidth: 680
|
|
12
|
+
minimumHeight: 640
|
|
13
|
+
visible: true
|
|
14
|
+
title: applicationTitle
|
|
15
|
+
color: Theme.background
|
|
16
|
+
font.pixelSize: guiPreferences.systemTextScaling
|
|
17
|
+
? guiPreferences.applicationFontPixelSize
|
|
18
|
+
: Theme.baseFontPixelSize
|
|
19
|
+
|
|
20
|
+
property string currentSurface: initialSurface
|
|
21
|
+
readonly property bool narrow: width < Theme.narrowBreakpoint
|
|
22
|
+
readonly property var sessionState: provider.state
|
|
23
|
+
readonly property var displayPreferences: guiPreferences
|
|
24
|
+
property string automaticBuildContext: ""
|
|
25
|
+
property string pendingCompletedDraftBuildContext: ""
|
|
26
|
+
property string previousPublishedDraftContext: ""
|
|
27
|
+
property bool previousDraftCompleted: false
|
|
28
|
+
readonly property string desktopApplicationVersion: applicationVersion
|
|
29
|
+
|
|
30
|
+
function observePublishedDraftState() {
|
|
31
|
+
const state = window.sessionState
|
|
32
|
+
const draft = state ? state.draft : null
|
|
33
|
+
const draftContext = (
|
|
34
|
+
draft && draft.account_id && draft.draft_id
|
|
35
|
+
? draft.account_id + ":" + draft.draft_id
|
|
36
|
+
: ""
|
|
37
|
+
)
|
|
38
|
+
const draftCompleted = Boolean(draft && draft.completed)
|
|
39
|
+
const completedTransition = Boolean(
|
|
40
|
+
draftContext
|
|
41
|
+
&& draftContext === window.previousPublishedDraftContext
|
|
42
|
+
&& !window.previousDraftCompleted
|
|
43
|
+
&& draftCompleted
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
window.previousPublishedDraftContext = draftContext
|
|
47
|
+
window.previousDraftCompleted = draftCompleted
|
|
48
|
+
if (completedTransition) {
|
|
49
|
+
window.pendingCompletedDraftBuildContext = draftContext
|
|
50
|
+
window.currentSurface = "build"
|
|
51
|
+
}
|
|
52
|
+
Qt.callLater(window.requestCompletedDraftBuild)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function requestCompletedDraftBuild() {
|
|
56
|
+
const state = window.sessionState
|
|
57
|
+
const errors = state ? state.errors : null
|
|
58
|
+
if (errors && errors.some(error => error && error.operation === "build")) {
|
|
59
|
+
window.automaticBuildContext = ""
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const progress = state ? state.progress : null
|
|
64
|
+
if (progress && progress.operation === "build")
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
if (window.currentSurface !== "build")
|
|
68
|
+
return
|
|
69
|
+
|
|
70
|
+
const draft = state ? state.draft : null
|
|
71
|
+
const pool = state ? state.pool : null
|
|
72
|
+
const cardData = state ? state.card_data : null
|
|
73
|
+
if (!draft || !draft.completed || !pool || pool.total_cards <= 0
|
|
74
|
+
|| !cardData || cardData.phase !== "ready")
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
const context = draft.account_id + ":" + draft.draft_id
|
|
78
|
+
const completedTransitionPending = (
|
|
79
|
+
window.pendingCompletedDraftBuildContext === context
|
|
80
|
+
)
|
|
81
|
+
if (!completedTransitionPending
|
|
82
|
+
&& (state.build || window.automaticBuildContext === context))
|
|
83
|
+
return
|
|
84
|
+
|
|
85
|
+
window.automaticBuildContext = context
|
|
86
|
+
window.pendingCompletedDraftBuildContext = ""
|
|
87
|
+
window.provider.requestBuild("")
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
onCurrentSurfaceChanged: Qt.callLater(window.requestCompletedDraftBuild)
|
|
91
|
+
onSessionStateChanged: window.observePublishedDraftState()
|
|
92
|
+
Component.onCompleted: window.observePublishedDraftState()
|
|
93
|
+
|
|
94
|
+
header: AppBar {
|
|
95
|
+
narrow: window.narrow
|
|
96
|
+
sessionState: window.sessionState
|
|
97
|
+
provider: window.provider
|
|
98
|
+
onSettingsRequested: window.currentSurface = "settings"
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
footer: StatusStrip {
|
|
102
|
+
sessionState: window.sessionState
|
|
103
|
+
displayPreferences: window.displayPreferences
|
|
104
|
+
applicationVersion: window.desktopApplicationVersion
|
|
105
|
+
narrow: window.narrow
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
AboutDialog {
|
|
109
|
+
id: aboutDialog
|
|
110
|
+
applicationVersion: window.desktopApplicationVersion
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
PrivacyDialog {
|
|
114
|
+
id: privacyDialog
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
RowLayout {
|
|
118
|
+
anchors.fill: parent
|
|
119
|
+
spacing: 0
|
|
120
|
+
|
|
121
|
+
NavigationRail {
|
|
122
|
+
Layout.fillHeight: true
|
|
123
|
+
currentSurface: window.currentSurface
|
|
124
|
+
compact: window.narrow
|
|
125
|
+
displayPreferences: window.displayPreferences
|
|
126
|
+
onSurfaceRequested: surface => window.currentSurface = surface
|
|
127
|
+
onAboutRequested: opener => {
|
|
128
|
+
aboutDialog.returnFocusItem = opener
|
|
129
|
+
aboutDialog.open()
|
|
130
|
+
}
|
|
131
|
+
onPrivacyRequested: opener => {
|
|
132
|
+
privacyDialog.returnFocusItem = opener
|
|
133
|
+
privacyDialog.open()
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
StackLayout {
|
|
138
|
+
Layout.fillWidth: true
|
|
139
|
+
Layout.fillHeight: true
|
|
140
|
+
Layout.margins: window.narrow ? 12 : 20
|
|
141
|
+
currentIndex: {
|
|
142
|
+
if (window.currentSurface === "build") return 1
|
|
143
|
+
if (window.currentSurface === "backtest") return 2
|
|
144
|
+
if (window.currentSurface === "settings") return 3
|
|
145
|
+
return 0
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
LiveDraftView {
|
|
149
|
+
sessionState: window.sessionState
|
|
150
|
+
recommendationModel: window.provider.recommendationsModel
|
|
151
|
+
narrow: window.narrow
|
|
152
|
+
displayPreferences: window.displayPreferences
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
BuildView {
|
|
156
|
+
sessionState: window.sessionState
|
|
157
|
+
narrow: window.narrow
|
|
158
|
+
displayPreferences: window.displayPreferences
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
BacktestView {
|
|
162
|
+
sessionState: window.sessionState
|
|
163
|
+
narrow: window.narrow
|
|
164
|
+
displayPreferences: window.displayPreferences
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
SettingsView {
|
|
168
|
+
sessionState: window.sessionState
|
|
169
|
+
narrow: window.narrow
|
|
170
|
+
displayPreferences: window.displayPreferences
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
pragma ComponentBehavior: Bound
|
|
2
|
+
|
|
3
|
+
import QtQuick 2.15
|
|
4
|
+
import QtQuick.Controls 2.15
|
|
5
|
+
import QtQuick.Layouts 1.15
|
|
6
|
+
|
|
7
|
+
Rectangle {
|
|
8
|
+
id: root
|
|
9
|
+
objectName: "navigationRail"
|
|
10
|
+
|
|
11
|
+
required property string currentSurface
|
|
12
|
+
required property bool compact
|
|
13
|
+
required property var displayPreferences
|
|
14
|
+
readonly property bool backtestNavigationVisible: root.displayPreferences.showBacktest
|
|
15
|
+
signal surfaceRequested(string surface)
|
|
16
|
+
signal aboutRequested(var opener)
|
|
17
|
+
signal privacyRequested(var opener)
|
|
18
|
+
|
|
19
|
+
color: Theme.surfaceLow
|
|
20
|
+
implicitWidth: compact ? 116 : 176
|
|
21
|
+
|
|
22
|
+
ButtonGroup {
|
|
23
|
+
id: navigationGroup
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
ColumnLayout {
|
|
27
|
+
anchors.fill: parent
|
|
28
|
+
anchors.margins: 12
|
|
29
|
+
spacing: 8
|
|
30
|
+
|
|
31
|
+
ColumnLayout {
|
|
32
|
+
Layout.fillWidth: true
|
|
33
|
+
visible: !root.compact
|
|
34
|
+
spacing: 6
|
|
35
|
+
|
|
36
|
+
Label {
|
|
37
|
+
Layout.fillWidth: true
|
|
38
|
+
text: "DRAFTOMEN"
|
|
39
|
+
color: Theme.primary
|
|
40
|
+
font.pixelSize: Theme.textPixelSize(14)
|
|
41
|
+
font.bold: true
|
|
42
|
+
font.letterSpacing: 1.2
|
|
43
|
+
horizontalAlignment: Text.AlignHCenter
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
Rectangle {
|
|
47
|
+
Layout.alignment: Qt.AlignHCenter
|
|
48
|
+
Layout.preferredWidth: 144
|
|
49
|
+
Layout.preferredHeight: 144
|
|
50
|
+
color: Theme.background
|
|
51
|
+
border.color: Theme.outline
|
|
52
|
+
border.width: 1
|
|
53
|
+
radius: Theme.radius
|
|
54
|
+
clip: true
|
|
55
|
+
|
|
56
|
+
Image {
|
|
57
|
+
objectName: "draftomenLogo"
|
|
58
|
+
anchors.fill: parent
|
|
59
|
+
source: "../assets/draftomen_logo.png"
|
|
60
|
+
sourceSize.width: 288
|
|
61
|
+
sourceSize.height: 288
|
|
62
|
+
fillMode: Image.PreserveAspectFit
|
|
63
|
+
smooth: true
|
|
64
|
+
mipmap: true
|
|
65
|
+
Accessible.name: "Draft Omen logo"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
Repeater {
|
|
71
|
+
model: [
|
|
72
|
+
{ key: "live", label: "Live Draft", shortLabel: "Draft", icon: "gavel" },
|
|
73
|
+
{ key: "build", label: "Deck Build", shortLabel: "Build", icon: "style" },
|
|
74
|
+
{ key: "backtest", label: "Backtest", shortLabel: "Backtest", icon: "history" }
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
delegate: DimensionalButton {
|
|
78
|
+
id: navigationButton
|
|
79
|
+
required property var modelData
|
|
80
|
+
|
|
81
|
+
Layout.fillWidth: true
|
|
82
|
+
Layout.preferredHeight: Theme.targetHeight
|
|
83
|
+
visible: navigationButton.modelData.key !== "backtest"
|
|
84
|
+
|| root.backtestNavigationVisible
|
|
85
|
+
text: root.compact
|
|
86
|
+
? navigationButton.modelData.shortLabel
|
|
87
|
+
: navigationButton.modelData.label
|
|
88
|
+
checkable: true
|
|
89
|
+
checked: root.currentSurface === navigationButton.modelData.key
|
|
90
|
+
accented: navigationButton.checked
|
|
91
|
+
ButtonGroup.group: navigationGroup
|
|
92
|
+
Accessible.name: navigationButton.modelData.label
|
|
93
|
+
Accessible.description: "Open the " + navigationButton.modelData.label + " surface."
|
|
94
|
+
onClicked: root.surfaceRequested(navigationButton.modelData.key)
|
|
95
|
+
|
|
96
|
+
contentItem: RowLayout {
|
|
97
|
+
anchors.fill: parent
|
|
98
|
+
anchors.topMargin: navigationButton.down ? Theme.controlPressOffset : 0
|
|
99
|
+
anchors.leftMargin: root.compact ? 6 : 10
|
|
100
|
+
anchors.rightMargin: root.compact ? 6 : 10
|
|
101
|
+
spacing: root.compact ? 6 : 10
|
|
102
|
+
|
|
103
|
+
Canvas {
|
|
104
|
+
id: navigationIcon
|
|
105
|
+
objectName: navigationButton.modelData.key + "NavigationIcon"
|
|
106
|
+
Layout.preferredWidth: 24
|
|
107
|
+
Layout.preferredHeight: 24
|
|
108
|
+
Layout.alignment: Qt.AlignVCenter
|
|
109
|
+
implicitWidth: 24
|
|
110
|
+
implicitHeight: 24
|
|
111
|
+
property string iconName: navigationButton.modelData.icon
|
|
112
|
+
property color iconColor: navigationButton.contentColor
|
|
113
|
+
|
|
114
|
+
onIconNameChanged: requestPaint()
|
|
115
|
+
onIconColorChanged: requestPaint()
|
|
116
|
+
Component.onCompleted: requestPaint()
|
|
117
|
+
|
|
118
|
+
onPaint: {
|
|
119
|
+
var context = getContext("2d")
|
|
120
|
+
context.clearRect(0, 0, width, height)
|
|
121
|
+
context.strokeStyle = iconColor
|
|
122
|
+
context.fillStyle = iconColor
|
|
123
|
+
context.lineWidth = 2
|
|
124
|
+
context.lineCap = "round"
|
|
125
|
+
context.lineJoin = "round"
|
|
126
|
+
|
|
127
|
+
if (iconName === "gavel") {
|
|
128
|
+
context.save()
|
|
129
|
+
context.translate(12, 11)
|
|
130
|
+
context.rotate(-Math.PI / 4)
|
|
131
|
+
context.fillRect(-4, -9, 8, 9)
|
|
132
|
+
context.fillRect(-1.5, 0, 3, 10)
|
|
133
|
+
context.restore()
|
|
134
|
+
context.fillRect(2, 20, 20, 2)
|
|
135
|
+
} else if (iconName === "style") {
|
|
136
|
+
context.strokeRect(4, 3, 16, 13)
|
|
137
|
+
context.strokeRect(2, 7, 16, 13)
|
|
138
|
+
context.beginPath()
|
|
139
|
+
context.moveTo(7, 11)
|
|
140
|
+
context.lineTo(15, 11)
|
|
141
|
+
context.stroke()
|
|
142
|
+
} else if (iconName === "history") {
|
|
143
|
+
context.beginPath()
|
|
144
|
+
context.arc(12, 12, 8, -Math.PI * 0.78, Math.PI * 1.64)
|
|
145
|
+
context.stroke()
|
|
146
|
+
context.beginPath()
|
|
147
|
+
context.moveTo(4, 4)
|
|
148
|
+
context.lineTo(4, 9)
|
|
149
|
+
context.lineTo(9, 7)
|
|
150
|
+
context.fill()
|
|
151
|
+
context.beginPath()
|
|
152
|
+
context.moveTo(12, 7)
|
|
153
|
+
context.lineTo(12, 12)
|
|
154
|
+
context.lineTo(16, 14)
|
|
155
|
+
context.stroke()
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
Text {
|
|
161
|
+
Layout.fillWidth: true
|
|
162
|
+
text: navigationButton.text
|
|
163
|
+
color: navigationButton.contentColor
|
|
164
|
+
font.bold: navigationButton.checked
|
|
165
|
+
verticalAlignment: Text.AlignVCenter
|
|
166
|
+
horizontalAlignment: Text.AlignLeft
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
Item {
|
|
173
|
+
Layout.fillHeight: true
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
ColumnLayout {
|
|
177
|
+
Layout.fillWidth: true
|
|
178
|
+
spacing: 6
|
|
179
|
+
|
|
180
|
+
DimensionalButton {
|
|
181
|
+
id: aboutButton
|
|
182
|
+
objectName: "aboutLink"
|
|
183
|
+
Layout.fillWidth: true
|
|
184
|
+
text: "About"
|
|
185
|
+
accented: true
|
|
186
|
+
accentColor: Theme.primary
|
|
187
|
+
accentContentColor: Theme.primaryContent
|
|
188
|
+
Accessible.name: "Open About dialog"
|
|
189
|
+
Accessible.description: "Show Draft Omen information and project website."
|
|
190
|
+
onClicked: root.aboutRequested(aboutButton)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
DimensionalButton {
|
|
194
|
+
id: privacyButton
|
|
195
|
+
objectName: "privacyLink"
|
|
196
|
+
Layout.fillWidth: true
|
|
197
|
+
text: "Privacy"
|
|
198
|
+
accented: true
|
|
199
|
+
accentColor: Theme.secondary
|
|
200
|
+
accentContentColor: Theme.secondaryContent
|
|
201
|
+
activeFocusOnTab: true
|
|
202
|
+
focusPolicy: Qt.StrongFocus
|
|
203
|
+
Accessible.role: Accessible.Button
|
|
204
|
+
Accessible.name: "Open Privacy dialog"
|
|
205
|
+
Accessible.description: "Show how Draft Omen handles your data."
|
|
206
|
+
onClicked: root.privacyRequested(privacyButton)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
Label {
|
|
210
|
+
Layout.fillWidth: true
|
|
211
|
+
text: root.compact ? "Read only" : "Arena integration · Read only"
|
|
212
|
+
color: Theme.textMuted
|
|
213
|
+
font.pixelSize: Theme.textPixelSize(10)
|
|
214
|
+
wrapMode: Text.WordWrap
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
Rectangle {
|
|
220
|
+
anchors.right: parent.right
|
|
221
|
+
width: 1
|
|
222
|
+
height: parent.height
|
|
223
|
+
color: Theme.outline
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|