GameSentenceMiner 2.18.20__py3-none-any.whl → 2.19.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.

Potentially problematic release.


This version of GameSentenceMiner might be problematic. Click here for more details.

@@ -83,6 +83,8 @@ try:
83
83
  except ImportError:
84
84
  mss = None
85
85
 
86
+ overlay_processor = None
87
+
86
88
  class OverlayThread(threading.Thread):
87
89
  """
88
90
  A thread to run the overlay processing loop.
@@ -91,7 +93,6 @@ class OverlayThread(threading.Thread):
91
93
  """
92
94
  def __init__(self):
93
95
  super().__init__()
94
- self.overlay_processor = OverlayProcessor()
95
96
  self.loop = asyncio.new_event_loop()
96
97
  self.daemon = True
97
98
  self.first_time_run = True
@@ -106,10 +107,10 @@ class OverlayThread(threading.Thread):
106
107
  while True:
107
108
  if overlay_server_thread.has_clients():
108
109
  if get_config().overlay.periodic:
109
- await self.overlay_processor.find_box_and_send_to_overlay('', True)
110
+ await overlay_processor.find_box_and_send_to_overlay('', True)
110
111
  await asyncio.sleep(get_config().overlay.periodic_interval)
111
112
  elif self.first_time_run:
112
- await self.overlay_processor.find_box_and_send_to_overlay('', False)
113
+ await overlay_processor.find_box_and_send_to_overlay('', False)
113
114
  self.first_time_run = False
114
115
  else:
115
116
  await asyncio.sleep(3)
@@ -569,7 +570,26 @@ class OverlayProcessor:
569
570
  # logger.info(f"Converted OneOCR results to percentages: {converted_results}")
570
571
  return converted_results
571
572
 
572
- overlay_processor = OverlayProcessor()
573
+ async def init_overlay_processor():
574
+ """
575
+ Initializes the overlay processor and starts the overlay thread.
576
+ This function can be called at application startup.
577
+ """
578
+ global overlay_processor
579
+ overlay_processor = OverlayProcessor()
580
+ overlay_thread = OverlayThread()
581
+ overlay_thread.start()
582
+ logger.info("Overlay processor initialized and thread started.")
583
+
584
+
585
+ def get_overlay_processor() -> OverlayProcessor:
586
+ """
587
+ Returns the initialized overlay processor instance.
588
+ """
589
+ global overlay_processor
590
+ if overlay_processor is None:
591
+ asyncio.run(init_overlay_processor())
592
+ return overlay_processor
573
593
 
574
594
  async def main_test_screenshot():
575
595
  """
@@ -1,16 +1,7 @@
1
- import asyncio
2
- from collections import defaultdict
3
1
  import datetime
4
- import json
5
- import os
6
- import queue
7
- import sqlite3
8
- import threading
9
2
  from dataclasses import dataclass
10
3
 
11
- from GameSentenceMiner.util.db import GameLinesTable
12
- from GameSentenceMiner.util.text_log import GameLine, initial_time
13
- from GameSentenceMiner.util.configuration import logger, DB_PATH
4
+ from GameSentenceMiner.util.text_log import GameLine
14
5
 
15
6
 
16
7
  @dataclass
@@ -42,60 +33,30 @@ class EventItem:
42
33
 
43
34
 
44
35
  class EventManager:
36
+ ids: set[str] = set()
45
37
  events: list[EventItem]
46
38
  events_dict: dict[str, EventItem] = {}
47
39
 
48
40
  def __init__(self):
49
41
  self.events = []
50
- self.ids = []
42
+ self.ids = set()
43
+ self.timed_out_ids = set()
51
44
  self.events_dict = {}
52
- self._connect()
53
- self._create_table()
54
- self._load_events_from_db()
55
- # self.close_connection()
56
-
57
- def _connect(self):
58
- self.conn = sqlite3.connect(DB_PATH)
59
- self.cursor = self.conn.cursor()
60
-
61
- def _create_table(self):
62
- self.cursor.execute("""
63
- CREATE TABLE IF NOT EXISTS events (
64
- event_id TEXT PRIMARY KEY,
65
- line_id TEXT,
66
- text TEXT,
67
- time TEXT
68
- )
69
- """)
70
- self.conn.commit()
71
-
72
- def _load_events_from_db(self):
73
- self.cursor.execute("SELECT * FROM events")
74
- rows = self.cursor.fetchall()
75
- for row in rows:
76
- event_id, line_id, text, timestamp = row
77
- timestamp = datetime.datetime.fromisoformat(timestamp)
78
- line = GameLine(line_id, text, timestamp, None, None, 0)
79
- event = EventItem(line, event_id, text, timestamp,
80
- False, timestamp < initial_time)
81
- self.events.append(event)
82
- self.ids.append(event_id)
83
- self.events_dict[event_id] = event
84
45
 
85
46
  def __iter__(self):
86
47
  return iter(self.events)
87
48
 
88
49
  def replace_events(self, new_events: list[EventItem]):
89
50
  self.events = new_events
51
+ self.events_dict = {event.id: event for event in new_events}
52
+ self.ids = {event.id for event in new_events}
90
53
 
91
54
  def add_gameline(self, line: GameLine):
92
55
  new_event = EventItem(line, line.id, line.text,
93
56
  line.time, False, False)
94
57
  self.events_dict[line.id] = new_event
95
- self.ids.append(line.id)
58
+ self.ids.add(line.id)
96
59
  self.events.append(new_event)
97
- # self.store_to_db(new_event)
98
- # event_queue.put(new_event)
99
60
  return new_event
100
61
 
101
62
  def reset_checked_lines(self):
@@ -107,8 +68,7 @@ class EventManager:
107
68
 
108
69
  def add_event(self, event):
109
70
  self.events.append(event)
110
- self.ids.append(event.id)
111
- event_queue.put(event)
71
+ self.ids.add(event.id)
112
72
 
113
73
  def get(self, event_id):
114
74
  return self.events_dict.get(event_id)
@@ -116,63 +76,27 @@ class EventManager:
116
76
  def get_ids(self):
117
77
  return self.ids
118
78
 
119
- def close_connection(self):
120
- if self.conn:
121
- self.conn.close()
122
-
123
79
  def clear_history(self):
124
- self.cursor.execute("DELETE FROM events WHERE time < ?",
125
- (initial_time.isoformat(),))
126
- logger.info(f"Cleared history before {initial_time.isoformat()}")
127
- self.conn.commit()
128
- # Clear the in-memory events as well
129
- event_manager.events = [
130
- event for event in event_manager if not event.history]
131
- event_manager.events_dict = {
132
- event.id: event for event in event_manager.events}
133
-
134
-
135
- class EventProcessor(threading.Thread):
136
- def __init__(self, event_queue, db_path):
137
- super().__init__()
138
- self.event_queue = event_queue
139
- self.db_path = db_path
140
- self.conn = None
141
- self.cursor = None
142
- self.daemon = True
143
-
144
- def _connect(self):
145
- self.conn = sqlite3.connect(self.db_path)
146
- self.cursor = self.conn.cursor()
147
-
148
- def run(self):
149
- self._connect()
150
- while True:
151
- try:
152
- event = self.event_queue.get()
153
- if event is None: # Exit signal
154
- break
155
- self._store_to_db(event)
156
- except Exception as e:
157
- logger.error(f"Error processing event: {e}")
158
- self._close_connection()
159
-
160
- def _store_to_db(self, event):
161
- self.cursor.execute("""
162
- INSERT INTO events (event_id, line_id, text, time)
163
- VALUES (?, ?, ?, ?)
164
- """, (event.id, event.line.id, event.text, event.time.isoformat()))
165
- self.conn.commit()
166
-
167
- def _close_connection(self):
168
- if self.conn:
169
- self.conn.close()
170
-
171
-
172
- # Global instances
173
- event_manager = EventManager()
174
- event_queue = queue.Queue()
175
-
176
- # Initialize the EventProcessor with the queue and event manager
177
- event_processor = EventProcessor(event_queue, DB_PATH)
178
- event_processor.start()
80
+ # Clear the in-memory events
81
+ self.events = [
82
+ event for event in self.events if not event.history]
83
+ self.events_dict = {
84
+ event.id: event for event in self.events}
85
+ self.ids = {event.id for event in self.events}
86
+
87
+ def remove_lines_by_ids(self, ids: list[str], timed_out: bool = False):
88
+ ids_to_remove = set(ids)
89
+
90
+ self.events = [event for event in self.events if event.id not in ids_to_remove]
91
+
92
+ for event_id in ids_to_remove:
93
+ self.events_dict.pop(event_id, None)
94
+
95
+ # Remove from set (much more efficient than rebuilding)
96
+ self.ids -= ids_to_remove
97
+ if timed_out:
98
+ self.timed_out_ids.update(ids_to_remove)
99
+
100
+
101
+ # Global instance
102
+ event_manager = EventManager()
@@ -325,6 +325,7 @@
325
325
  </div>
326
326
  </div>
327
327
  </div>
328
+ {% include 'components/settings-modal.html' %}
328
329
  </div>
329
330
 
330
331
  <!-- Include shared JavaScript configuration -->