-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEventManager.py
272 lines (221 loc) · 8.35 KB
/
EventManager.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
import glob
from datetime import datetime
from pathlib import Path
from colorama import init, Fore, Back, Style
from Package import Package
from QrCoder import QrCoder
class EventManager(object):
"""Events Manager
Choose option from menu:
> Help usage\t\t\t\t - show context help
> Select your source file\t - select CSV, JSON, XML file with data
\t - Select file from current path
> Generate from source file\t - run generate QR codes from selected file
\t - All QR images are saved to a directory by the source file name
> Exit the program\t\t\t - exit form program :)
"""
def __init__(self):
"""Events Manager Constructor
"""
init()
self.pkg = Package()
# Connect Qr Class
self.qr = QrCoder()
# Registry all events
self._eventsRegistry = {}
# Current event worker
self._this_event = None
"""
# self._events - Events Items
# self._events - this list -> dict for many events
# Example: [{'name': 'select_file', 'method': 'select_file'}, {'name': 'select_file', 'method': 'select_file'}]
#
# self._events - this dict for one event
# Example: {'name': 'select_file', 'method': 'select_file'}
# Supported keys
# - title As view title menu item
# - name Unique Name for item
# - method Event method name (def. as `name`)
# - property Props for item
"""
self._events = [
{
'title': 'Help usage',
'name': 'help_usage',
},
{
'title': 'Select source file',
'name': 'select_file',
# 'method': 'select_file',
# 'property': 'select_file'
},
{
'title': 'Generate from source file',
'name': 'generate',
},
{
'title': 'Exit the program',
'name': 'exit',
}
]
self.menu()
@classmethod
def __name__(cls):
return str(cls.__name__)
def menu(self):
# Menu wrapper for first run
print(self.pkg.package_info())
print('=== MENU ===')
print('Hey! Here is what I can do:')
while True:
self._menu_items()
def _menu_items(self):
# Show Menu items
index = 1
for event in self._events:
prop = ''
try:
if hasattr(__class__, 'select_file') and event['name'] == 'select_file' and self.qr.src_fullname:
prop = f"(selected: {self.qr.src_fullname})"
except KeyError:
prop = ''
index_item = "%s%s%s" % (Style.BRIGHT + Fore.RED, index, Style.RESET_ALL)
title_item = "%s%s%s" % (Fore.GREEN, event['title'], Style.RESET_ALL)
print("\t%s. %s %s" % (index_item, title_item, prop))
index = index + 1
response = None
while not isinstance(response, int):
try:
response = int(input('I have a choose: '))
response = response - 1
except ValueError:
continue
try:
if self._events[response] in self._events:
self.execute(self._events[response])
except IndexError:
print('Oooh... Are you serious? Come on again.')
def _register(self):
# Register event task
self._eventsRegistry.update(
{
id(self._this_event):
{
'id': id(self._this_event),
'event': self._this_event,
'time': datetime.now().strftime('%m.%d.%Y %H:%M:%S.%f')
}
})
def _register_status(self, status):
# Mutable event status task in Register
self._eventsRegistry[id(self._this_event)]['status'] = status
def _prepare(self):
# Prepare event model
if 'name' not in self._this_event:
raise KeyError('Important Event field `name` not exits')
fields = ['method', 'property']
for field in fields:
if field not in self._this_event:
self._this_event[field] = self._this_event['name']
if self._this_event['method'].startswith('event_') is False:
self._this_event['method'] = f"event_{self._this_event['method']}"
def events(self, events=[]):
pass
# @staticmethod
def execute(self, events):
"""
Run event input node
:mutable: true
"""
if isinstance(events, list):
for event in events:
self.execute(event)
if not isinstance(events, dict):
raise TypeError('Event dictionary not found')
self._this_event = events
try:
self._prepare()
self._register()
except KeyError as e:
raise e
if callable(getattr(__class__, self._this_event['method'])):
value = getattr(__class__, self._this_event['method'])(self)
if value is not [None, False]:
setattr(__class__, self._this_event['name'], value)
self._register_status(1)
else:
raise RuntimeError(f"Event {self._this_event['name']} not exist or not callable")
def event_help_usage(self):
"""
View doc-block for Supported Classes
"""
objects = [self, self.qr]
for obj in objects:
print(f"\r\nMethods {obj.__name__()}") # Method Heading
for func in dir(obj):
__obj = getattr(obj, func)
if callable(__obj) \
and (not func.startswith("__") or func.startswith("__init__")) \
and not func.endswith("Class"):
if func == "__init__":
scope = 'Description: '
func = ''
elif func.startswith("_"):
scope = 'private'
else:
scope = 'public'
func = f'{func}()'
if __obj.__doc__ is not None:
print(f'\t%s %s' % (scope, func), __obj.__doc__)
print(f"=============\r\n")
@staticmethod
def event_select_file(self):
"""
Event input filename
"""
files = [f for ext in self.qr.supported_exts for f in glob.glob(f'*.{ext}')]
if not files:
raise RuntimeError(
'No files found. Required list with extensions: (%s)' % ', '.join(self.qr.supported_exts)
)
print(f'Select data source file')
index = 1
for file in files:
index_item = "%s%s%s" % (Style.BRIGHT + Fore.RED, index, Style.RESET_ALL)
file_item = "%s%s%s" % (Fore.GREEN, file, Style.RESET_ALL)
print(f'\t%s. %s' % (index_item, file_item))
index = index + 1
file = int(input(f'I have a choose > '))
file = file - 1
if file == '':
return self.execute({'name': 'select_file'})
my_file = Path(files[file])
if not my_file.is_file():
print(f'File named {my_file} does not exist')
return self.execute({'name': 'select_file'})
# Confirmation Event
response = True
response = input(f'Are you sure and want to continue with the file {Fore.GREEN}{Style.BRIGHT}{my_file}{Style.RESET_ALL}? [Y/n]\r\n')
# Failure
if response == 'n' or response == 'N':
return self.execute({'name': 'select_file'})
# Success
if response or response == '' or response == 'Y' or response == 'y':
print(f'File {my_file} selected for generation')
setattr(__class__, 'select_file', str(my_file))
self.qr.data_filename(str(my_file))
def event_generate(self):
"""
Make qr codes from selected list
"""
while hasattr(__class__, 'select_file') is False:
print('Source file not specified. Select a file first!')
self.execute({'name': 'select_file'})
self.qr.make()
@staticmethod
def event_exit(self):
"""
Exit from program
"""
print('The program was stopped by the user')
exit(1)