Coverage for GuiAutoImport.py: 0%

232 statements  

« 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 

12 

13import Importer 

14from optparse import OptionParser 

15import Configuration 

16 

17import interlocks 

18 

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") 

23 

24if os.name == "nt": 

25 import win32console 

26 

27def to_raw(string): 

28 return fr"{string}" 

29 

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 

39 

40 self.input_settings = {} 

41 self.pipe_to_hud = None 

42 

43 self.importer = Importer.Importer(self, self.settings, self.config, self.sql, zmq_port="5556") 

44 

45 self.importer.setCallHud(True) 

46 self.importer.setQuiet(False) 

47 self.importer.setHandCount(0) 

48 self.importer.setMode('auto') 

49 

50 self.server = settings['db-host'] 

51 self.user = settings['db-user'] 

52 self.password = settings['db-password'] 

53 self.database = settings['db-databaseName'] 

54 

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 

62 

63 def setupGui(self): 

64 self.setLayout(QVBoxLayout()) 

65 

66 hbox = QHBoxLayout() 

67 

68 self.intervalLabel = QLabel(("Time between imports in seconds:")) 

69 

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) 

75 

76 hbox = QHBoxLayout() 

77 vbox1 = QVBoxLayout() 

78 vbox2 = QVBoxLayout() 

79 hbox.addLayout(vbox1) 

80 hbox.addLayout(vbox2) 

81 self.layout().addLayout(hbox) 

82 

83 self.addSites(vbox1, vbox2) 

84 

85 self.textview = QTextEdit() 

86 self.textview.setReadOnly(True) 

87 

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) 

93 

94 self.addText(("Auto Import Ready.")) 

95 

96 def addText(self, text): 

97 self.textview.moveCursor(QTextCursor.End) 

98 self.textview.insertPlainText(text) 

99# end of GuiAutoImport.__init__ 

100 

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() 

108 

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 

115 

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 

124 

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')) 

130 

131 return False 

132 

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 

148 

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 

158 

159 

160 

161 def startClicked(self): 

162 """runs when user clicks start on auto import tab""" 

163 

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. 

167 

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. 

173 

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 

214 

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) 

226 

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) 

239 

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) 

256 

257 

258 #end def GuiAutoImport.startClicked 

259 

260 def get_vbox(self): 

261 """returns the vbox of this thread""" 

262 return self.mainVBox 

263 #end def get_vbox 

264 

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) 

271 

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) 

278 

279 browseButton=QPushButton(("Browse...")) 

280 browseButton.hackdata = [(site, type)] + [dirPath] 

281 browseButton.clicked.connect(self.browseClicked)#, [(site,type)] + [dirPath]) 

282 hbox2.addWidget(browseButton) 

283 

284 label = QLabel("filter:") 

285 hbox2.addWidget(label) 

286 

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) 

293 

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) 

302 

303 params = self.config.get_site_parameters(site) 

304 paths = self.config.get_default_paths(site) 

305 

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']] 

308 

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)) 

317 

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() 

322 

323 config = Configuration.Config() 

324 

325 settings = {} 

326 if os.name == 'nt': settings['os'] = 'windows' 

327 else: settings['os'] = 'linuxmac' 

328 

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:]) 

334 

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)