Coverage for GuiAutoImport.py: 0%
232 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-27 18:50 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-27 18:50 +0000
1from __future__ import print_function
2#import L10n
3#_ = L10n.get_translation()
4import subprocess
5import traceback
6import os
7import sys
8import logging
9from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, QSpinBox, QPushButton, QLineEdit, QTextEdit, QCheckBox, QFileDialog
10from PyQt5.QtCore import QTimer
11from PyQt5.QtGui import QTextCursor
13import Importer
14from optparse import OptionParser
15import Configuration
17import interlocks
19if __name__ == "__main__":
20 Configuration.set_logfile("fpdb-log.txt")
21# logging has been set up in fpdb.py or HUD_main.py, use their settings:
22log = logging.getLogger("importer")
24if os.name == "nt":
25 import win32console
27def to_raw(string):
28 return fr"{string}"
30class GuiAutoImport(QWidget):
31 def __init__(self, settings, config, sql = None, parent = None, cli = False):
32 if not cli:
33 QWidget.__init__(self, parent)
34 self.importtimer = None
35 self.settings = settings
36 self.config = config
37 self.sql = sql
38 self.parent = parent
40 self.input_settings = {}
41 self.pipe_to_hud = None
43 self.importer = Importer.Importer(self, self.settings, self.config, self.sql, zmq_port="5556")
45 self.importer.setCallHud(True)
46 self.importer.setQuiet(False)
47 self.importer.setHandCount(0)
48 self.importer.setMode('auto')
50 self.server = settings['db-host']
51 self.user = settings['db-user']
52 self.password = settings['db-password']
53 self.database = settings['db-databaseName']
55 if cli == False:
56 self.setupGui()
57 else:
58 # TODO: Separate the code that grabs the directories from config
59 # Separate the calls to the Importer API
60 # Create a timer interface that doesn't rely on GTK
61 raise NotImplementedError
63 def setupGui(self):
64 self.setLayout(QVBoxLayout())
66 hbox = QHBoxLayout()
68 self.intervalLabel = QLabel(("Time between imports in seconds:"))
70 self.intervalEntry = QSpinBox()
71 self.intervalEntry.setValue(int(self.config.get_import_parameters().get("interval")))
72 hbox.addWidget(self.intervalLabel)
73 hbox.addWidget(self.intervalEntry)
74 self.layout().addLayout(hbox)
76 hbox = QHBoxLayout()
77 vbox1 = QVBoxLayout()
78 vbox2 = QVBoxLayout()
79 hbox.addLayout(vbox1)
80 hbox.addLayout(vbox2)
81 self.layout().addLayout(hbox)
83 self.addSites(vbox1, vbox2)
85 self.textview = QTextEdit()
86 self.textview.setReadOnly(True)
88 self.doAutoImportBool = False
89 self.startButton = QCheckBox(("Start Auto Import"))
90 self.startButton.stateChanged.connect(self.startClicked)
91 self.layout().addWidget(self.startButton)
92 self.layout().addWidget(self.textview)
94 self.addText(("Auto Import Ready."))
96 def addText(self, text):
97 self.textview.moveCursor(QTextCursor.End)
98 self.textview.insertPlainText(text)
99# end of GuiAutoImport.__init__
101 def browseClicked(self):
102# runs when user clicks one of the browse buttons in the auto import tab"""
103# Browse is not valid while hud is running, so return immediately
104 if (self.pipe_to_hud):
105 return
106 data = self.sender().hackdata
107 current_path = data[1].text()
109 newdir = QFileDialog.getExistingDirectory(self, caption=("Please choose the path that you want to Auto Import"),directory=current_path)
110 if newdir:
111 #print dia_chooser.get_filename(), 'selected'
112 data[1].setText(newdir)
113 self.input_settings[data[0]][0] = newdir
114 #end def GuiAutoImport.browseClicked
116 def do_import(self):
117 """Callback for timer to do an import iteration."""
118 if self.doAutoImportBool:
119 self.importer.autoSummaryGrab()
120 self.importer.runUpdated()
121 self.addText(".")
122 return True
123 return False
125 def reset_startbutton(self):
126 if self.pipe_to_hud is not None:
127 self.startButton.set_label((u'Stop Auto Import'))
128 else:
129 self.startButton.set_label((u'Start Auto Import'))
131 return False
133 def detect_hh_dirs(self, widget, data):
134 """Attempt to find user hand history directories for enabled sites"""
135 the_sites = self.config.get_supported_sites()
136 for site in the_sites:
137 params = self.config.get_site_parameters(site)
138 if params['enabled'] == True:
139 print(("DEBUG:") + " " + ("Detecting hand history directory for site: '%s'") % site)
140 if os.name == 'posix':
141 if self.posix_detect_hh_dirs(site):
142 #data[1].set_text(dia_chooser.get_filename())
143 self.input_settings[(site, 'hh')][0]
144 pass
145 elif os.name == 'nt':
146 # Sorry
147 pass
149 def posix_detect_hh_dirs(self, site):
150 defaults = {
151 'PokerStars': '~/.wine/drive_c/Program Files/PokerStars/HandHistory',
152 }
153 if site == 'PokerStars':
154 directory = os.path.expanduser(defaults[site])
155 for file in [file for file in os.listdir(directory) if not file in [".",".."]]:
156 print(file)
157 return False
161 def startClicked(self):
162 """runs when user clicks start on auto import tab"""
164 # Check to see if we have an open file handle to the HUD and open one if we do not.
165 # bufsize = 1 means unbuffered
166 # We need to close this file handle sometime.
168 # TODO: Allow for importing from multiple dirs - REB 29AUG2008
169 # As presently written this function does nothing if there is already a pipe open.
170 # That is not correct. It should open another dir for importing while piping the
171 # results to the same pipe. This means that self.path should be a a list of dirs
172 # to watch.
174 if self.startButton.isChecked():
175 # - Does the lock acquisition need to be more sophisticated for multiple dirs?
176 # (see comment above about what to do if pipe already open)
177 # - Ideally we want to release the lock if the auto-import is killed by some
178 # kind of exception - is this possible?
179 if self.settings['global_lock'].acquire(wait=False, source="AutoImport"):
180 self.addText("\n" + ("Global lock taken ... Auto Import Started.") + "\n")
181 self.doAutoImportBool = True
182 self.intervalEntry.setEnabled(False)
183 if self.pipe_to_hud is None:
184 print('start hud- pipe_to_hud is none:')
185 try:
186 if self.config.install_method == "exe":
187 command = "HUD_main.exe"
188 bs = 0
189 elif self.config.install_method == "app":
190 base_path = sys._MEIPASS if getattr(sys, 'frozen', False) else sys.path[0]
191 command = os.path.join(base_path, "HUD_main")
192 if not os.path.isfile(command):
193 raise FileNotFoundError(f"HUD_main not found at {command}")
194 bs = 1
195 elif os.name == 'nt':
196 path = to_raw(sys.path[0])
197 print("start hud- path", path)
198 path2 = os.getcwd()
199 print("start hud- path2", path2)
200 if win32console.GetConsoleWindow() == 0:
201 command = 'pythonw "' + path + '\HUD_main.pyw" ' + self.settings['cl_options']
202 print("start hud-comand1", command)
203 else:
204 command = 'python "' + path + '\HUD_main.pyw" ' + self.settings['cl_options']
205 print("start hud-comand2", command)
206 bs = 0
207 else:
208 base_path = sys._MEIPASS if getattr(sys, 'frozen', False) else sys.path[0] or os.getcwd()
209 command = os.path.join(base_path, 'HUD_main.pyw')
210 if not os.path.isfile(command):
211 self.addText("\n" + ('*** %s was not found') % (command))
212 command = [command, ] + str.split(self.settings['cl_options'], '.')
213 bs = 1
215 print(("opening pipe to HUD"))
216 print(f"Running {command.__repr__()}")
217 if self.config.install_method == "exe" or (os.name == "nt" and win32console.GetConsoleWindow() == 0):
218 self.pipe_to_hud = subprocess.Popen(command, bufsize=bs,
219 stdin=subprocess.PIPE,
220 stdout=subprocess.PIPE,
221 stderr=subprocess.PIPE,
222 universal_newlines=True
223 )
224 else:
225 self.pipe_to_hud = subprocess.Popen(command, bufsize=bs, stdin=subprocess.PIPE, universal_newlines=True)
227 except Exception as e:
228 self.addText("\n" + ("*** GuiAutoImport Error opening pipe:") + " " + traceback.format_exc())
229 # TODO: log.warning() ?
230 else:
231 for (site, type) in self.input_settings:
232 self.importer.addImportDirectory(self.input_settings[(site, type)][0], monitor=True, site=(site, type))
233 self.addText("\n * " + ("Add %s import directory %s") % (site, self.input_settings[(site, type)][0]))
234 self.do_import()
235 interval = self.intervalEntry.value()
236 self.importtimer = QTimer()
237 self.importtimer.timeout.connect(self.do_import)
238 self.importtimer.start(interval * 1000)
240 else:
241 self.addText("\n" + ("Auto Import aborted.") + ("Global lock not available."))
242 else: # toggled off
243 self.doAutoImportBool = False
244 self.importtimer = None
245 self.importer.autoSummaryGrab(True)
246 self.settings['global_lock'].release()
247 self.addText("\n" + ("Stopping Auto Import.") + ("Global lock released."))
248 if self.pipe_to_hud and self.pipe_to_hud.poll() is not None:
249 self.addText("\n * " + ("Stop Auto Import") + ": " + ("HUD already terminated."))
250 else:
251 if self.pipe_to_hud:
252 self.pipe_to_hud.terminate()
253 print(self.pipe_to_hud.stdin, "\n")
254 self.pipe_to_hud = None
255 self.intervalEntry.setEnabled(True)
258 #end def GuiAutoImport.startClicked
260 def get_vbox(self):
261 """returns the vbox of this thread"""
262 return self.mainVBox
263 #end def get_vbox
265 #Create the site line given required info and setup callbacks
266 #enabling and disabling sites from this interface not possible
267 #expects a box to layout the line horizontally
268 def createSiteLine(self, hbox1, hbox2, site, iconpath, type, path, filter_name, active = True):
269 label = QLabel(("%s auto-import:") % site)
270 hbox1.addWidget(label)
272 dirPath=QLineEdit()
273 dirPath.setText(path)
274 hbox1.addWidget(dirPath)
275# Anything typed into dirPath was never recognised (only the browse button works)
276# so just prevent entry to avoid user confusion
277 dirPath.setReadOnly(True)
279 browseButton=QPushButton(("Browse..."))
280 browseButton.hackdata = [(site, type)] + [dirPath]
281 browseButton.clicked.connect(self.browseClicked)#, [(site,type)] + [dirPath])
282 hbox2.addWidget(browseButton)
284 label = QLabel("filter:")
285 hbox2.addWidget(label)
287# Anything typed into filter was never recognised
288# so just grey it out to avoid user confusion
289 filterLine = QLineEdit()
290 filterLine.setText(filter_name)
291 filterLine.setEnabled(False)
292 hbox2.addWidget(filterLine)
294 def addSites(self, vbox1, vbox2):
295 the_sites = self.config.get_supported_sites()
296 #log.debug("addSites: the_sites="+str(the_sites))
297 for site in the_sites:
298 pathHBox1 = QHBoxLayout()
299 vbox1.addLayout(pathHBox1)
300 pathHBox2 = QHBoxLayout()
301 vbox2.addLayout(pathHBox2)
303 params = self.config.get_site_parameters(site)
304 paths = self.config.get_default_paths(site)
306 self.createSiteLine(pathHBox1, pathHBox2, site, False, 'hh', paths['hud-defaultPath'], params['converter'], params['enabled'])
307 self.input_settings[(site, 'hh')] = [paths['hud-defaultPath']] + [params['converter']]
309 if 'hud-defaultTSPath' in paths:
310 pathHBox1 = QHBoxLayout()
311 vbox1.addLayout(pathHBox1)
312 pathHBox2 = QHBoxLayout()
313 vbox2.addLayout(pathHBox2)
314 self.createSiteLine(pathHBox1, pathHBox2, site, False, 'ts', paths['hud-defaultTSPath'], params['summaryImporter'], params['enabled'])
315 self.input_settings[(site, 'ts')] = [paths['hud-defaultTSPath']] + [params['summaryImporter']]
316 #log.debug("addSites: input_settings="+str(self.input_settings))
318if __name__== "__main__":
319 parser = OptionParser()
320 parser.add_option("-q", "--quiet", action="store_false", dest="gui", default=True, help="don't start gui")
321 (options, argv) = parser.parse_args()
323 config = Configuration.Config()
325 settings = {}
326 if os.name == 'nt': settings['os'] = 'windows'
327 else: settings['os'] = 'linuxmac'
329 settings.update(config.get_db_parameters())
330 settings.update(config.get_import_parameters())
331 settings.update(config.get_default_paths())
332 settings['global_lock'] = interlocks.InterProcessLock(name="fpdb_global_lock")
333 settings['cl_options'] = '.'.join(sys.argv[1:])
335 if(options.gui == True):
336 from PyQt5.QtWidgets import QApplication, QMainWindow
337 app = QApplication([])
338 i = GuiAutoImport(settings, config, None, None)
339 main_window = QMainWindow()
340 main_window.setCentralWidget(i)
341 main_window.show()
342 app.exec_()
343 else:
344 i = GuiAutoImport(settings, config, cli = True)