-
Notifications
You must be signed in to change notification settings - Fork 26
/
game2text.py
229 lines (187 loc) · 6.68 KB
/
game2text.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
import eel
import threading, os, platform, time, concurrent.futures
thread_pool_ref = concurrent.futures.ThreadPoolExecutor # Necessary for distribution to import ThreadPoolExecutor before app code
from pathlib import Path
from ocr import detect_and_log
from translate import multi_translate
from hotkeys import hotkey_map
from util import RepeatedTimer, create_directory_if_not_exists, get_default_browser_name, get_PID_list, format_output
from textractor import Textractor
from tools import path_to_textractor, open_folder_textractor_path
from pynput import keyboard
from clipboard import clipboard_to_output, text_to_clipboard
from logger import get_time_string, log_text, log_media, update_log_text
from ankiconnect import invoke, get_anki_models, update_anki_models, create_anki_note, fetch_anki_fields
from imageprofile import export_image_profile, load_image_profiles, open_image_profile
from gamescript import load_game_scripts, open_game_script
from dictionary import load_all_dictionaries, look_up, get_local_dictionaries, load_dictionary, get_jpod_audio_url
from config import r_config, r_config_all, r_config_section, w_config, APP_CONFIG, LOG_CONFIG, TEXTHOOKER_CONFIG
session_start_time = get_time_string()
textractor = None
# run_eel()
# Set web files folder and optionally specify which file types to check for eel.expose()
# *Default allowed_extensions are: ['.js', '.html', '.txt', '.htm', '.xhtml']
def close(page, sockets):
if not sockets:
os._exit(0)
@eel.expose
def recognize_image(engine, image, orientation):
return detect_and_log(engine, image, orientation, session_start_time, get_time_string())
@eel.expose
def log_output(text):
log_id = get_time_string()
log_text(session_start_time, log_id, text)
log_media(session_start_time, log_id)
return log_id
@eel.expose
def export_image_filter_profile(profile):
return export_image_profile(profile)
@eel.expose
def load_image_filter_profiles():
return load_image_profiles()
@eel.expose
def open_image_filter_profile():
return open_image_profile()
@eel.expose
def load_game_text_scripts():
return load_game_scripts()
@eel.expose
def open_game_text_script():
return open_game_script()
@eel.expose
def update_main_window_text(text):
is_log_text = False
eel.updateOutput(text, is_log_text)()
@eel.expose
def update_log_window_text(log_id, text):
update_log_text(log_id, session_start_time, text)
eel.updateLogDataById(log_id, {'text': text})()
@eel.expose
def translate(text):
return multi_translate(text)
@eel.expose
def monitor_clipboard():
if clipboard_timer.is_running:
clipboard_timer.stop()
else:
clipboard_timer.start()
@eel.expose
def copy_text_to_clipboard(text):
text_to_clipboard(text)
@eel.expose
def read_config(section, key):
return r_config(section, key)
@eel.expose
def read_config_all():
return r_config_all()
@eel.expose
def update_config(section, d):
return w_config(section, d)
@eel.expose
def invoke_anki(action, params={}):
return invoke(action, params)
@eel.expose
def get_anki_card_models():
return get_anki_models()
@eel.expose
def fetch_anki_fields_by_modals(model_names):
fetch_anki_fields_thread = threading.Thread(target=fetch_anki_fields, args=((model_names,)))
fetch_anki_fields_thread.start()
@eel.expose
def update_anki_card_models(ankiModels):
return update_anki_models(ankiModels)
@eel.expose
def create_note(note_data):
return create_anki_note(note_data)
@eel.expose
def set_dictionary(dictionary):
load_dictionary(dictionary)
@eel.expose
def get_jpod_url(kanji, kana):
return get_jpod_audio_url(kanji=kanji, kana=kana)
@eel.expose
def get_dictionaries():
return get_local_dictionaries()
@eel.expose
def look_up_dictionary(word):
return look_up(word)
@eel.expose
def get_path_to_textractor():
return path_to_textractor()
@eel.expose
def open_folder_for_textractor():
return open_folder_textractor_path()
@eel.expose
def get_PIDs():
return get_PID_list()
@eel.expose
def attach_process(pids):
textractor_thread = threading.Thread(target=start_textractor, args=[pids,])
textractor_thread.start()
@eel.expose
def detach_process(pids):
try:
global textractor
for pid in pids:
textractor.detach(pid)
except Exception as e:
print('error', str(e))
return 'Error: failed to detach processes' + str(e)
def start_textractor(pids):
try:
global textractor
textractor = Textractor(executable_path=path_to_textractor(), callback=monitor_textractor)
time.sleep(1)
textractor.attach_multiple(pids)
textractor.read()
except Exception as e:
print('error', str(e))
return 'Error: failed to attach processes' + str(e)
@eel.expose
def hook_code(code, pids):
try:
global textractor
for pid in pids:
textractor.hook(code, pid)
except Exception as e:
print(e)
return 'Error: failed to hook code'
def monitor_textractor(output_objects):
texthooker_config = r_config_section(TEXTHOOKER_CONFIG)
output_objects = format_output(
output_objects=output_objects,
remove_repeat_mode=texthooker_config['remove_repeat_mode'].lower(),
is_remove_duplicates= texthooker_config['remove_duplicates'] == 'true',
is_remove_spaces=texthooker_config['remove_spaces'] == 'true')
eel.textractorPipe(output_objects)
@eel.expose
def open_new_window(html_file, height=900, width=600):
eel.start(html_file,
close_callback=close,
mode=get_default_browser_name() if r_config(APP_CONFIG, "browser") == 'default' else r_config(APP_CONFIG, "browser"),
host=r_config(APP_CONFIG, "host"),
size=(width, height),
port = int(r_config(APP_CONFIG, "port")))
return
def run_eel():
eel.init('web', allowed_extensions=['.js', '.html', '.map'])
browser_mode = get_default_browser_name() if r_config(APP_CONFIG, "browser") == 'default' else r_config(APP_CONFIG, "browser")
paths_config = r_config_section('PATHS')
if 'browser' in paths_config:
eel.browsers.set_path(browser_mode, paths_config['browser'])
eel.start('index.html',
close_callback=close,
mode=browser_mode,
host=r_config(APP_CONFIG, "host"),
port=int(r_config(APP_CONFIG, "port"))
)
main_thread = threading.Thread(target=run_eel, args=())
main_thread.start()
# Thread to load dictionaries
dictionary_thread = threading.Thread(target=load_all_dictionaries, args=())
dictionary_thread.start()
# Thread to export clipboard text continuously
clipboard_timer = RepeatedTimer(1, clipboard_to_output)
clipboard_timer.stop() # stop the initial timer
with keyboard.GlobalHotKeys(hotkey_map) as listener:
listener.join()