ankigammon 1.0.6__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.
- ankigammon/__init__.py +7 -0
- ankigammon/__main__.py +6 -0
- ankigammon/analysis/__init__.py +13 -0
- ankigammon/analysis/score_matrix.py +391 -0
- ankigammon/anki/__init__.py +6 -0
- ankigammon/anki/ankiconnect.py +216 -0
- ankigammon/anki/apkg_exporter.py +111 -0
- ankigammon/anki/card_generator.py +1325 -0
- ankigammon/anki/card_styles.py +1054 -0
- ankigammon/gui/__init__.py +8 -0
- ankigammon/gui/app.py +192 -0
- ankigammon/gui/dialogs/__init__.py +10 -0
- ankigammon/gui/dialogs/export_dialog.py +594 -0
- ankigammon/gui/dialogs/import_options_dialog.py +201 -0
- ankigammon/gui/dialogs/input_dialog.py +762 -0
- ankigammon/gui/dialogs/note_dialog.py +93 -0
- ankigammon/gui/dialogs/settings_dialog.py +420 -0
- ankigammon/gui/dialogs/update_dialog.py +373 -0
- ankigammon/gui/format_detector.py +377 -0
- ankigammon/gui/main_window.py +1611 -0
- ankigammon/gui/resources/down-arrow.svg +3 -0
- ankigammon/gui/resources/icon.icns +0 -0
- ankigammon/gui/resources/icon.ico +0 -0
- ankigammon/gui/resources/icon.png +0 -0
- ankigammon/gui/resources/style.qss +402 -0
- ankigammon/gui/resources.py +26 -0
- ankigammon/gui/update_checker.py +259 -0
- ankigammon/gui/widgets/__init__.py +8 -0
- ankigammon/gui/widgets/position_list.py +166 -0
- ankigammon/gui/widgets/smart_input.py +268 -0
- ankigammon/models.py +356 -0
- ankigammon/parsers/__init__.py +7 -0
- ankigammon/parsers/gnubg_match_parser.py +1094 -0
- ankigammon/parsers/gnubg_parser.py +468 -0
- ankigammon/parsers/sgf_parser.py +290 -0
- ankigammon/parsers/xg_binary_parser.py +1097 -0
- ankigammon/parsers/xg_text_parser.py +688 -0
- ankigammon/renderer/__init__.py +5 -0
- ankigammon/renderer/animation_controller.py +391 -0
- ankigammon/renderer/animation_helper.py +191 -0
- ankigammon/renderer/color_schemes.py +145 -0
- ankigammon/renderer/svg_board_renderer.py +791 -0
- ankigammon/settings.py +315 -0
- ankigammon/thirdparty/__init__.py +7 -0
- ankigammon/thirdparty/xgdatatools/__init__.py +17 -0
- ankigammon/thirdparty/xgdatatools/xgimport.py +160 -0
- ankigammon/thirdparty/xgdatatools/xgstruct.py +1032 -0
- ankigammon/thirdparty/xgdatatools/xgutils.py +118 -0
- ankigammon/thirdparty/xgdatatools/xgzarc.py +260 -0
- ankigammon/utils/__init__.py +13 -0
- ankigammon/utils/gnubg_analyzer.py +590 -0
- ankigammon/utils/gnuid.py +577 -0
- ankigammon/utils/move_parser.py +204 -0
- ankigammon/utils/ogid.py +326 -0
- ankigammon/utils/xgid.py +387 -0
- ankigammon-1.0.6.dist-info/METADATA +352 -0
- ankigammon-1.0.6.dist-info/RECORD +61 -0
- ankigammon-1.0.6.dist-info/WHEEL +5 -0
- ankigammon-1.0.6.dist-info/entry_points.txt +2 -0
- ankigammon-1.0.6.dist-info/licenses/LICENSE +21 -0
- ankigammon-1.0.6.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"""Export XG decisions to Anki .apkg file using genanki."""
|
|
2
|
+
|
|
3
|
+
import genanki
|
|
4
|
+
import random
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import List
|
|
7
|
+
|
|
8
|
+
from ankigammon.models import Decision
|
|
9
|
+
from ankigammon.anki.card_generator import CardGenerator
|
|
10
|
+
from ankigammon.anki.card_styles import MODEL_NAME, CARD_CSS
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ApkgExporter:
|
|
14
|
+
"""
|
|
15
|
+
Export XG decisions to Anki .apkg file.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, output_dir: Path, deck_name: str = "My AnkiGammon Deck"):
|
|
19
|
+
"""
|
|
20
|
+
Initialize the APKG exporter.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
output_dir: Directory for output files
|
|
24
|
+
deck_name: Name of the Anki deck
|
|
25
|
+
"""
|
|
26
|
+
self.output_dir = Path(output_dir)
|
|
27
|
+
self.output_dir.mkdir(parents=True, exist_ok=True)
|
|
28
|
+
self.deck_name = deck_name
|
|
29
|
+
|
|
30
|
+
self.deck_id = random.randrange(1 << 30, 1 << 31)
|
|
31
|
+
self.model_id = random.randrange(1 << 30, 1 << 31)
|
|
32
|
+
|
|
33
|
+
self.model = self._create_model()
|
|
34
|
+
self.deck = genanki.Deck(self.deck_id, self.deck_name)
|
|
35
|
+
|
|
36
|
+
def _create_model(self) -> genanki.Model:
|
|
37
|
+
"""Create the Anki note model."""
|
|
38
|
+
return genanki.Model(
|
|
39
|
+
self.model_id,
|
|
40
|
+
MODEL_NAME,
|
|
41
|
+
fields=[
|
|
42
|
+
{'name': 'Front'},
|
|
43
|
+
{'name': 'Back'},
|
|
44
|
+
],
|
|
45
|
+
templates=[
|
|
46
|
+
{
|
|
47
|
+
'name': 'Card 1',
|
|
48
|
+
'qfmt': '{{Front}}',
|
|
49
|
+
'afmt': '{{Back}}',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
css=CARD_CSS
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
def export(
|
|
56
|
+
self,
|
|
57
|
+
decisions: List[Decision],
|
|
58
|
+
output_file: str = "xg_deck.apkg",
|
|
59
|
+
show_options: bool = False,
|
|
60
|
+
color_scheme: str = "classic",
|
|
61
|
+
interactive_moves: bool = False,
|
|
62
|
+
orientation: str = "counter-clockwise",
|
|
63
|
+
progress_callback: callable = None
|
|
64
|
+
) -> str:
|
|
65
|
+
"""
|
|
66
|
+
Export decisions to an APKG file.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
decisions: List of Decision objects
|
|
70
|
+
output_file: Output filename
|
|
71
|
+
show_options: Show multiple choice options
|
|
72
|
+
color_scheme: Board color scheme name
|
|
73
|
+
interactive_moves: Enable interactive move visualization
|
|
74
|
+
orientation: Board orientation
|
|
75
|
+
progress_callback: Optional callback for progress updates
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
Path to generated APKG file
|
|
79
|
+
"""
|
|
80
|
+
from ankigammon.renderer.color_schemes import get_scheme
|
|
81
|
+
from ankigammon.renderer.svg_board_renderer import SVGBoardRenderer
|
|
82
|
+
|
|
83
|
+
scheme = get_scheme(color_scheme)
|
|
84
|
+
renderer = SVGBoardRenderer(color_scheme=scheme, orientation=orientation)
|
|
85
|
+
|
|
86
|
+
card_gen = CardGenerator(
|
|
87
|
+
output_dir=self.output_dir,
|
|
88
|
+
show_options=show_options,
|
|
89
|
+
interactive_moves=interactive_moves,
|
|
90
|
+
renderer=renderer,
|
|
91
|
+
progress_callback=progress_callback
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
for i, decision in enumerate(decisions):
|
|
95
|
+
if progress_callback:
|
|
96
|
+
progress_callback(f"Position {i+1}/{len(decisions)}: Starting...")
|
|
97
|
+
card_data = card_gen.generate_card(decision, card_id=f"card_{i}")
|
|
98
|
+
|
|
99
|
+
note = genanki.Note(
|
|
100
|
+
model=self.model,
|
|
101
|
+
fields=[card_data['front'], card_data['back']],
|
|
102
|
+
tags=card_data['tags']
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
self.deck.add_note(note)
|
|
106
|
+
|
|
107
|
+
output_path = self.output_dir / output_file
|
|
108
|
+
package = genanki.Package(self.deck)
|
|
109
|
+
package.write_to_file(str(output_path))
|
|
110
|
+
|
|
111
|
+
return str(output_path)
|