Browse Source

troop selection: dump troop file

Bastien Sevajol 5 years ago
parent
commit
7cb345ede9

+ 2 - 0
config.yaml View File

29
     team_stash: "opencombat.strategy.team.stash.TeamStash"
29
     team_stash: "opencombat.strategy.team.stash.TeamStash"
30
     teams_schema: "opencombat/strategy/teams.xsd"
30
     teams_schema: "opencombat/strategy/teams.xsd"
31
     units_schema: "opencombat/strategy/units.xsd"
31
     units_schema: "opencombat/strategy/units.xsd"
32
+    troop_dumper: "opencombat.strategy.troops.TroopDumper"
33
+    troop_schema: "opencombat/strategy/troops.xsd"
32
     cache_dir_path: 'cache'
34
     cache_dir_path: 'cache'
33
     include_path:
35
     include_path:
34
       maps:
36
       maps:

+ 13 - 3
opencombat/strategy/manager.py View File

1
 # coding: utf-8
1
 # coding: utf-8
2
+import typing
3
+
2
 from synergine2.config import Config
4
 from synergine2.config import Config
3
 from synergine2.log import get_logger
5
 from synergine2.log import get_logger
4
 
6
 
7
+from opencombat.strategy.team.model import TeamModel
5
 from opencombat.strategy.team.stash import TeamStash
8
 from opencombat.strategy.team.stash import TeamStash
6
 from opencombat.strategy.troops import TroopClassBuilder
9
 from opencombat.strategy.troops import TroopClassBuilder
7
 from opencombat.strategy.unit.stash import UnitStash
10
 from opencombat.strategy.unit.stash import UnitStash
17
         self._config = config
20
         self._config = config
18
         self._logger = get_logger('TroopManager', config)
21
         self._logger = get_logger('TroopManager', config)
19
 
22
 
20
-        builder = TroopClassBuilder(config)
21
-        self._unit_stash = builder.get_unit_stash(
23
+        self._builder = TroopClassBuilder(config)
24
+        self._unit_stash = self._builder.get_unit_stash(
22
             units_file_path,
25
             units_file_path,
23
         )
26
         )
24
-        self._team_stash = builder.get_team_stash(
27
+        self._team_stash = self._builder.get_team_stash(
25
             units_file_path,
28
             units_file_path,
26
             teams_file_path,
29
             teams_file_path,
27
         )
30
         )
33
     @property
36
     @property
34
     def unit_stash(self) -> UnitStash:
37
     def unit_stash(self) -> UnitStash:
35
         return self._unit_stash
38
         return self._unit_stash
39
+
40
+    def get_troop_dump(
41
+        self,
42
+        countries_troops: typing.Dict[str, typing.List[TeamModel]],
43
+    ):
44
+        dumper = self._builder.get_troop_dumper()
45
+        return dumper.get_troop_dump(countries_troops)

+ 45 - 0
opencombat/strategy/selection/gui.py View File

1
 # coding: utf-8
1
 # coding: utf-8
2
+import os
2
 import typing
3
 import typing
3
 from tkinter import Tk
4
 from tkinter import Tk
4
 from tkinter import Button
5
 from tkinter import Button
6
 from tkinter import StringVar
7
 from tkinter import StringVar
7
 from tkinter import OptionMenu
8
 from tkinter import OptionMenu
8
 from tkinter import W
9
 from tkinter import W
10
+from tkinter import E
11
+from tkinter import messagebox
9
 from tkinter.ttk import Combobox
12
 from tkinter.ttk import Combobox
10
 from tkinter.ttk import Treeview
13
 from tkinter.ttk import Treeview
11
 
14
 
15
+
16
+import time
12
 from synergine2.config import Config
17
 from synergine2.config import Config
13
 
18
 
14
 from opencombat.gui import Gui
19
 from opencombat.gui import Gui
20
+from opencombat.strategy.manager import TroopManager
15
 from opencombat.strategy.team.stash import TeamStash
21
 from opencombat.strategy.team.stash import TeamStash
16
 
22
 
17
 
23
 
21
         config: Config,
27
         config: Config,
22
         master: Tk,
28
         master: Tk,
23
         team_stash: TeamStash,
29
         team_stash: TeamStash,
30
+        troop_manager: TroopManager,
24
         countries: typing.List[str],
31
         countries: typing.List[str],
32
+        troops_dir_path: str = '.',
25
     ) -> None:
33
     ) -> None:
26
         super().__init__(config, master)
34
         super().__init__(config, master)
27
         self._master.title('Troops selection')
35
         self._master.title('Troops selection')
36
+        self._countries = countries
28
         self._team_stash = team_stash
37
         self._team_stash = team_stash
38
+        self._troop_manager = troop_manager
39
+        self._troops_dir_path = troops_dir_path
29
         self._countries_troops = {}  # type: typing.Dict[str, typing.List[TeamModel]]  # nopep8
40
         self._countries_troops = {}  # type: typing.Dict[str, typing.List[TeamModel]]  # nopep8
30
 
41
 
31
         # Widgets
42
         # Widgets
72
         self._troops_view.column('#0', stretch=YES)
83
         self._troops_view.column('#0', stretch=YES)
73
         self._troops_view.column('#1', stretch=YES)
84
         self._troops_view.column('#1', stretch=YES)
74
 
85
 
86
+        self._generate_troops_var = StringVar(self._master)
87
+        self._generate_troops_button = Button(
88
+            self._master,
89
+            textvariable=self._generate_troops_var,
90
+            command=self._generate_troops,
91
+        )
92
+        self._generate_troops_var.set('Generate troops')
93
+
75
         # Layout
94
         # Layout
76
         self._select_country_menu.grid(row=0, column=0, sticky=W)
95
         self._select_country_menu.grid(row=0, column=0, sticky=W)
77
         self._teams_list.grid(row=1, column=0, sticky=W)
96
         self._teams_list.grid(row=1, column=0, sticky=W)
78
         self._add_troop_button.grid(row=2, column=0, sticky=W)
97
         self._add_troop_button.grid(row=2, column=0, sticky=W)
79
         self._troops_view.grid(row=3, column=0, sticky=W)
98
         self._troops_view.grid(row=3, column=0, sticky=W)
80
         self._remove_troop_button.grid(row=4, column=0, sticky=W)
99
         self._remove_troop_button.grid(row=4, column=0, sticky=W)
100
+        self._generate_troops_button.grid(row=4, column=0, sticky=E)
81
 
101
 
82
         # Default behaviours
102
         # Default behaviours
83
         self._selected_country_var.set(countries[0])
103
         self._selected_country_var.set(countries[0])
153
                 text=team.name,
173
                 text=team.name,
154
                 values=('o' * len(team.units,))
174
                 values=('o' * len(team.units,))
155
             )
175
             )
176
+
177
+    def _generate_troops(self, *args, **kwargs) -> None:
178
+        # Must have team(s) in all countries
179
+        if len(self._countries_troops.keys()) == len(self._countries) \
180
+                and all(self._countries_troops.values()):
181
+
182
+            troops_file_path = os.path.join(
183
+                self._troops_dir_path,
184
+                'troops_{}.xml'.format(str(time.time())),
185
+            )
186
+
187
+            self._logger.info('Generate troops into file "{}"'.format(
188
+                troops_file_path,
189
+            ))
190
+
191
+            troops_xml = self._troop_manager.get_troop_dump(
192
+                self._countries_troops,
193
+            )
194
+            with open(troops_file_path, 'w+') as file:
195
+                file.write(troops_xml)
196
+        else:
197
+            messagebox.showinfo(
198
+                'Missing information',
199
+                'All countries must have teams',
200
+            )

+ 58 - 1
opencombat/strategy/troops.py View File

1
 # coding: utf-8
1
 # coding: utf-8
2
+import typing
3
+
4
+from lxml import etree
5
+
2
 from synergine2.config import Config
6
 from synergine2.config import Config
3
 from synergine2.log import get_logger
7
 from synergine2.log import get_logger
4
 
8
 
9
+from opencombat.strategy.team.model import TeamModel
5
 from opencombat.strategy.team.stash import TeamStash
10
 from opencombat.strategy.team.stash import TeamStash
6
 from opencombat.strategy.unit.stash import UnitStash
11
 from opencombat.strategy.unit.stash import UnitStash
7
-from opencombat.util import get_class_from_string_path
12
+from opencombat.util import get_class_from_string_path, pretty_xml
13
+
14
+
15
+class TroopDumper(object):
16
+    def __init__(
17
+        self,
18
+        config: Config,
19
+    ) -> None:
20
+        self._config = config
21
+        self._logger = get_logger('TroopDumper', config)
22
+
23
+    def get_troop_dump(
24
+        self,
25
+        countries_troops: typing.Dict[str, typing.List[TeamModel]],
26
+    ) -> str:
27
+        troops_template = self._config.resolve(
28
+            'global.troops_template',
29
+            'opencombat/strategy/troops_template.xml',
30
+        )
31
+        with open(troops_template, 'r') as xml_file:
32
+            template_str = xml_file.read()
33
+
34
+        parser = etree.XMLParser(remove_blank_text=True)
35
+        state_root = etree.fromstring(
36
+            template_str.encode('utf-8'),
37
+            parser,
38
+        )
39
+
40
+        for country, teams in countries_troops.items():
41
+            for team in teams:
42
+                troop_element = etree.SubElement(state_root, 'troop')
43
+                troop_element.attrib['country'] = country
44
+                troop_element.attrib['team_id'] = team.id
45
+
46
+        return pretty_xml(
47
+            etree.tostring(
48
+                state_root,
49
+            ).decode('utf-8'),
50
+        )
8
 
51
 
9
 
52
 
10
 class TroopClassBuilder(object):
53
 class TroopClassBuilder(object):
52
             teams_file_path,
95
             teams_file_path,
53
             unit_stash=unit_stash,
96
             unit_stash=unit_stash,
54
         )
97
         )
98
+
99
+    def get_troop_dumper(self) -> TroopDumper:
100
+        class_address = self._config.resolve(
101
+            'global.troop_dumper',
102
+            'opencombat.strategy.troops.TroopDumper',
103
+        )
104
+        class_ = get_class_from_string_path(
105
+            self._config,
106
+            class_address,
107
+        )
108
+
109
+        return class_(
110
+            self._config,
111
+        )

+ 9 - 0
select_troops.py View File

13
     units_file_path: str,
13
     units_file_path: str,
14
     teams_file_path: str,
14
     teams_file_path: str,
15
     countries: typing.List[str],
15
     countries: typing.List[str],
16
+    troops_dir_path: str = '.',
16
 ) -> None:
17
 ) -> None:
17
     config = Config()
18
     config = Config()
18
     config.load_yaml('config.yaml')
19
     config.load_yaml('config.yaml')
28
         config,
29
         config,
29
         master=master,
30
         master=master,
30
         team_stash=troop_manager.team_stash,
31
         team_stash=troop_manager.team_stash,
32
+        troop_manager=troop_manager,
31
         countries=countries,
33
         countries=countries,
34
+        troops_dir_path=troops_dir_path,
32
     )
35
     )
33
     master.mainloop()
36
     master.mainloop()
34
 
37
 
52
         action='append',
55
         action='append',
53
         dest='countries',
56
         dest='countries',
54
     )
57
     )
58
+    parser.add_argument(
59
+        '--troops-dir-path',
60
+        dest='troops_dir_path',
61
+        default='.',
62
+    )
55
     args = parser.parse_args()
63
     args = parser.parse_args()
56
 
64
 
57
     main(
65
     main(
58
         units_file_path=args.units_file_path,
66
         units_file_path=args.units_file_path,
59
         teams_file_path=args.teams_file_path,
67
         teams_file_path=args.teams_file_path,
60
         countries=args.countries,
68
         countries=args.countries,
69
+        troops_dir_path=args.troops_dir_path,
61
     )
70
     )

+ 2 - 0
test_config.yaml View File

29
     team_stash: "opencombat.strategy.team.stash.TeamStash"
29
     team_stash: "opencombat.strategy.team.stash.TeamStash"
30
     teams_schema: "opencombat/strategy/teams.xsd"
30
     teams_schema: "opencombat/strategy/teams.xsd"
31
     units_schema: "opencombat/strategy/units.xsd"
31
     units_schema: "opencombat/strategy/units.xsd"
32
+    troop_dumper: "opencombat.strategy.troops.TroopDumper"
33
+    troop_schema: "opencombat/strategy/troops.xsd"
32
     cache_dir_path: 'cache'
34
     cache_dir_path: 'cache'
33
     include_path:
35
     include_path:
34
       maps:
36
       maps: