def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.nextWorkerInput = ["[]", "1"] self.bestPropScore = -1 self.clear_worker_table() self.DataCollector = JsonReader(self) self.connect(self.DataCollector, QtCore.SIGNAL("received_data"), self.received) self.connect(self.DataCollector, QtCore.SIGNAL("worker_updated"), self.update_worker) self.connect(self.DataCollector, QtCore.SIGNAL("round_started"), self.start_round) self.connect(self.DataCollector, QtCore.SIGNAL("worker_input_changed"), self.update_worker_input) self.connect(self.DataCollector, QtCore.SIGNAL("problem_state_changed"), self.update_problem_state) self.connect(self.DataCollector, QtCore.SIGNAL("all_data"), self.update_all) self.DataCollector.start() # proposition tab QtCore.QObject.connect(self.ui.cbxId, QtCore.SIGNAL("currentIndexChanged(int)"), self.cbxId_indexChanged) self.paintBox = PaintBox(self.ui.tabProposition) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.paintBox.sizePolicy().hasHeightForWidth()) self.paintBox.setSizePolicy(sizePolicy) self.ui.gridLayout_4.addWidget(self.paintBox, 1, 0, 1, 1) # io tab QtCore.QObject.connect(self.ui.btnSend, QtCore.SIGNAL("clicked()"), self.btnSend_clicked) QtCore.QObject.connect(self.ui.edtSend, QtCore.SIGNAL("returnPressed()"), self.btnSend_clicked)
def batch_mode(input_file_path: str, output_file_path: str) -> None: """ batch_mode Process regex and test strings in batch mode. Output results to output_file_path. :param input_file_path: The input JSON file path. :param output_file_path: The output JSON file path. """ # read the input file and get an object representation of it. regex_result_list = JsonReader(input_file_path).regex_input_list if not regex_result_list: logging.critical( f'Batch mode failed: {input_file_path} in improper format.') return # Run all test strings. _run_all_test_strings_in_list(regex_result_list) # Write results to the output_file_path JsonWriter().write_json_output_file(output_file_path, regex_result_list) logging.info('Batch mode completed on input file ' + str(input_file_path) + ' and output file ' + str(output_file_path))
def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.nextWorkerInput = ["[]", "1"] self.bestPropScore = -1 self.clear_worker_table() self.DataCollector = JsonReader(self) self.connect(self.DataCollector, QtCore.SIGNAL("received_data"), self.received) self.connect(self.DataCollector, QtCore.SIGNAL("worker_updated"), self.update_worker) self.connect(self.DataCollector, QtCore.SIGNAL("round_started"), self.start_round) self.connect(self.DataCollector, QtCore.SIGNAL("worker_input_changed"), self.update_worker_input) self.connect(self.DataCollector, QtCore.SIGNAL("problem_state_changed"), self.update_problem_state) self.connect(self.DataCollector, QtCore.SIGNAL("all_data"), self.update_all) self.DataCollector.start() # proposition tab QtCore.QObject.connect(self.ui.cbxId, QtCore.SIGNAL("currentIndexChanged(int)"), self.cbxId_indexChanged) self.paintBox = PaintBox(self.ui.tabProposition) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.paintBox.sizePolicy().hasHeightForWidth()) self.paintBox.setSizePolicy(sizePolicy) self.ui.gridLayout_4.addWidget(self.paintBox, 1, 0, 1, 1) # io tab QtCore.QObject.connect(self.ui.btnSend, QtCore.SIGNAL("clicked()"), self.btnSend_clicked) QtCore.QObject.connect(self.ui.edtSend, QtCore.SIGNAL("returnPressed()"), self.btnSend_clicked)
class MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.nextWorkerInput = ["[]", "1"] self.bestPropScore = -1 self.clear_worker_table() self.DataCollector = JsonReader(self) self.connect(self.DataCollector, QtCore.SIGNAL("received_data"), self.received) self.connect(self.DataCollector, QtCore.SIGNAL("worker_updated"), self.update_worker) self.connect(self.DataCollector, QtCore.SIGNAL("round_started"), self.start_round) self.connect(self.DataCollector, QtCore.SIGNAL("worker_input_changed"), self.update_worker_input) self.connect(self.DataCollector, QtCore.SIGNAL("problem_state_changed"), self.update_problem_state) self.connect(self.DataCollector, QtCore.SIGNAL("all_data"), self.update_all) self.DataCollector.start() # proposition tab QtCore.QObject.connect(self.ui.cbxId, QtCore.SIGNAL("currentIndexChanged(int)"), self.cbxId_indexChanged) self.paintBox = PaintBox(self.ui.tabProposition) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.paintBox.sizePolicy().hasHeightForWidth()) self.paintBox.setSizePolicy(sizePolicy) self.ui.gridLayout_4.addWidget(self.paintBox, 1, 0, 1, 1) # io tab QtCore.QObject.connect(self.ui.btnSend, QtCore.SIGNAL("clicked()"), self.btnSend_clicked) QtCore.QObject.connect(self.ui.edtSend, QtCore.SIGNAL("returnPressed()"), self.btnSend_clicked) def closeEvent(self, e): self.send(json.dumps({'action': 'quit program'})) self.DataCollector.terminate( ) # TODO: "This function is dangerous and its use is discouraged" self.DataCollector.wait() e.accept() app.exit() ############################### ## main menu / buttons ## ############################### ## io tab def btnSend_clicked(self): msg = self.ui.edtSend.text() self.send(msg) self.ui.edtSend.clear() def cbxId_indexChanged(self, idx): ## DEBUG #sys.stderr.write(">> cbxId_indexChanged %d\n" % idx) #sys.stderr.flush() self.display_proposition_by_cbxId_index(idx) ####################### ## JSON events ## ####################### def update_worker(self, id, proposition, propCaption, propScore, processedScore, problemScore, blocked, working): ## DEBUG #sys.stderr.write("[json] update_worker:\n") #sys.stderr.write(" id : %s\n" % id) #sys.stderr.write(" proposition: %s\n" % proposition) #sys.stderr.write(" caption : %s\n" % propCaption) #sys.stderr.write(" score : %s\n" % propScore) #sys.stderr.flush() if id in self.worker: (workerName, bestProposition, bestPropCaption, bestPropScore) = self.worker[id] self.worker[id] = (workerName, proposition, propCaption, propScore) if (blocked == "no"): ## valid proposition: check if better if propScore > self.bestPropScore: self.bestPropScore = propScore ## auto switch to best proposition newCbxIndex = self.ui.cbxId.findText(id) if newCbxIndex == self.ui.cbxId.currentIndex(): self.display_proposition_by_cbxId_index(newCbxIndex) else: self.ui.cbxId.setCurrentIndex(newCbxIndex) else: if propScore < 0: ## invalid proposition: find and display the next better proposition if 1 == 1 or self.ui.cbxId.text() == id: nextBestId = id nextBestScore = -1 for i in self.worker.keys(): (n, p, c, s) = self.worker[i] if s > nextBestScore: nextBestId = i nextBestScore = s self.bestPropScore = nextBestScore ## switch to next better proposition newCbxIndex = self.ui.cbxId.findText(nextBestId) if newCbxIndex == self.ui.cbxId.currentIndex(): self.display_proposition_by_cbxId_index( newCbxIndex) else: self.ui.cbxId.setCurrentIndex(newCbxIndex) def start_round(self, round): ## DEBUG #sys.stderr.write("[json] start_round:\n") #sys.stderr.write(" round: %s\n" % round) #sys.stderr.flush() ## activate proposition tab self.ui.tabWidget.setCurrentIndex(2) self.paintBox.setSquareSize(int(self.nextWorkerInput[1])) self.ui.lblInput.setText("<html><body>" + "<p><b>Square: </b>" + self.nextWorkerInput[1] + "</p>" + "<p><b>Squares </b>(" + str(self.nextWorkerInput[0].count(",")) + ")<b>: </b>" + self.nextWorkerInput[0].replace(",", ", ") + "</p></body></html>") self.bestPropScore = -1 self.ui.lblWorker.setText("") self.ui.lblScore.setText("") for workerId in self.worker.keys(): (name, proposition, propCaption, propScore) = self.worker[workerId] self.worker[workerId] = (name, "[]", "", 0) self.paintBox.drawProposition("[]") def update_worker_input(self, workerInput): ## DEBUG #sys.stderr.write("[json] update_worker_input:\n") #sys.stderr.write(" workerInput: %s\n" % workerInput) #sys.stderr.flush() self.nextWorkerInput = workerInput def update_problem_state(self, problemState): self.ui.lblState.setText(problemState.replace(",", ", ")) def update_all(self, running, workerList, problemList, problemIdx, round, workerInput, problemState): ## DEBUG #sys.stderr.write("[json] update_all:\n") #sys.stderr.write(" running : %s\n" % running) #sys.stderr.write(" workerList: %s\n" % workerList) #sys.stderr.write(" ...\n") #sys.stderr.flush() self.clear_worker_table() for id, name, group, proposition, caption, score, processedScore, problemScore, blocked, working in workerList: self.add_worker(id, name, group, proposition, caption, score, processedScore, problemScore, blocked, working) self.update_worker_input(workerInput) self.update_problem_state(problemState) if running: self.start_round(round) ############################# ## private functions ## ############################# def send(self, msg): self.ui.txtRecv.appendHtml( "<span style='font-weight:bold;color:red'>send:</span> " + escape_html(msg).rstrip("\n").replace("\n", "<br />")) print(msg) sys.stdout.flush() def received(self, msg): self.ui.txtRecv.appendHtml( "<span style='font-weight:bold;color:blue'>recv:</span> " + escape_html(msg).rstrip("\n").replace("\n", "<br />")) def clear_worker_table(self): self.worker = {} self.ui.cbxId.clear() def add_worker(self, id, name, group, proposition, propCaption, propScore, processedScore, problemScore, blocked, working): self.worker[id] = (name, proposition, propCaption, propScore) self.ui.cbxId.clear() self.ui.cbxId.addItems(sorted(self.worker.keys())) def display_proposition_by_cbxId_index(self, idx): ## DEBUG #sys.stderr.write(">> display_proposition_by_cbxId_index %d\n" % idx) #sys.stderr.flush() if idx > -1: workerId = str(self.ui.cbxId.itemText(idx)) if workerId in self.worker: ## DEBUG #sys.stderr.write(">> %s\n" % workerId) #sys.stderr.flush() (workerName, lastProposition, lastPropCaption, lastPropScore) = self.worker[workerId] self.ui.lblWorker.setText( "<html><body><p style='font-size:12pt'><b>" + workerName + "</b></p></body></html>") self.ui.lblScore.setText( "<html><body><p style='font-size:12pt'><b>Score: </b>" + str(lastPropScore) + "</p></body></html>") self.paintBox.drawProposition(lastProposition)
class MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.nextWorkerInput = ["[]", "1"] self.bestPropScore = -1 self.clear_worker_table() self.DataCollector = JsonReader(self) self.connect(self.DataCollector, QtCore.SIGNAL("received_data"), self.received) self.connect(self.DataCollector, QtCore.SIGNAL("worker_updated"), self.update_worker) self.connect(self.DataCollector, QtCore.SIGNAL("round_started"), self.start_round) self.connect(self.DataCollector, QtCore.SIGNAL("worker_input_changed"), self.update_worker_input) self.connect(self.DataCollector, QtCore.SIGNAL("problem_state_changed"), self.update_problem_state) self.connect(self.DataCollector, QtCore.SIGNAL("all_data"), self.update_all) self.DataCollector.start() # proposition tab QtCore.QObject.connect(self.ui.cbxId, QtCore.SIGNAL("currentIndexChanged(int)"), self.cbxId_indexChanged) self.paintBox = PaintBox(self.ui.tabProposition) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.paintBox.sizePolicy().hasHeightForWidth()) self.paintBox.setSizePolicy(sizePolicy) self.ui.gridLayout_4.addWidget(self.paintBox, 1, 0, 1, 1) # io tab QtCore.QObject.connect(self.ui.btnSend, QtCore.SIGNAL("clicked()"), self.btnSend_clicked) QtCore.QObject.connect(self.ui.edtSend, QtCore.SIGNAL("returnPressed()"), self.btnSend_clicked) def closeEvent(self, e): self.send(json.dumps({'action': 'quit program'})) self.DataCollector.terminate() # TODO: "This function is dangerous and its use is discouraged" self.DataCollector.wait() e.accept() app.exit() ############################### ## main menu / buttons ## ############################### ## io tab def btnSend_clicked(self): msg = self.ui.edtSend.text() self.send(msg) self.ui.edtSend.clear() def cbxId_indexChanged(self, idx): ## DEBUG #sys.stderr.write(">> cbxId_indexChanged %d\n" % idx) #sys.stderr.flush() self.display_proposition_by_cbxId_index(idx) ####################### ## JSON events ## ####################### def update_worker(self, id, proposition, propCaption, propScore, processedScore, problemScore, blocked, working): ## DEBUG #sys.stderr.write("[json] update_worker:\n") #sys.stderr.write(" id : %s\n" % id) #sys.stderr.write(" proposition: %s\n" % proposition) #sys.stderr.write(" caption : %s\n" % propCaption) #sys.stderr.write(" score : %s\n" % propScore) #sys.stderr.flush() if id in self.worker: (workerName, bestProposition, bestPropCaption, bestPropScore) = self.worker[id] self.worker[id] = (workerName, proposition, propCaption, propScore) if (blocked == "no"): ## valid proposition: check if better if propScore > self.bestPropScore: self.bestPropScore = propScore ## auto switch to best proposition newCbxIndex = self.ui.cbxId.findText(id) if newCbxIndex == self.ui.cbxId.currentIndex(): self.display_proposition_by_cbxId_index(newCbxIndex) else: self.ui.cbxId.setCurrentIndex(newCbxIndex) else: if propScore < 0: ## invalid proposition: find and display the next better proposition if 1 == 1 or self.ui.cbxId.text() == id: nextBestId = id nextBestScore = -1 for i in self.worker.keys(): (n, p, c, s) = self.worker[i] if s > nextBestScore: nextBestId = i nextBestScore = s self.bestPropScore = nextBestScore ## switch to next better proposition newCbxIndex = self.ui.cbxId.findText(nextBestId) if newCbxIndex == self.ui.cbxId.currentIndex(): self.display_proposition_by_cbxId_index(newCbxIndex) else: self.ui.cbxId.setCurrentIndex(newCbxIndex) def start_round(self, round): ## DEBUG #sys.stderr.write("[json] start_round:\n") #sys.stderr.write(" round: %s\n" % round) #sys.stderr.flush() ## activate proposition tab self.ui.tabWidget.setCurrentIndex(2) self.paintBox.setSquareSize(int(self.nextWorkerInput[1])) self.ui.lblInput.setText("<html><body>" + "<p><b>Square: </b>" + self.nextWorkerInput[1] + "</p>" + "<p><b>Squares </b>(" + str(self.nextWorkerInput[0].count(",")) + ")<b>: </b>" + self.nextWorkerInput[0].replace(",", ", ") + "</p></body></html>") self.bestPropScore = -1 self.ui.lblWorker.setText("") self.ui.lblScore.setText("") for workerId in self.worker.keys(): (name, proposition, propCaption, propScore) = self.worker[workerId] self.worker[workerId] = (name, "[]", "", 0) self.paintBox.drawProposition("[]") def update_worker_input(self, workerInput): ## DEBUG #sys.stderr.write("[json] update_worker_input:\n") #sys.stderr.write(" workerInput: %s\n" % workerInput) #sys.stderr.flush() self.nextWorkerInput = workerInput def update_problem_state(self, problemState): self.ui.lblState.setText(problemState.replace(",", ", ")) def update_all(self, running, workerList, problemList, problemIdx, round, workerInput, problemState): ## DEBUG #sys.stderr.write("[json] update_all:\n") #sys.stderr.write(" running : %s\n" % running) #sys.stderr.write(" workerList: %s\n" % workerList) #sys.stderr.write(" ...\n") #sys.stderr.flush() self.clear_worker_table() for id, name, group, proposition, caption, score, processedScore, problemScore, blocked, working in workerList: self.add_worker(id, name, group, proposition, caption, score, processedScore, problemScore, blocked, working) self.update_worker_input(workerInput) self.update_problem_state(problemState) if running: self.start_round(round) ############################# ## private functions ## ############################# def send(self, msg): self.ui.txtRecv.appendHtml("<span style='font-weight:bold;color:red'>send:</span> " + escape_html(msg).rstrip("\n").replace("\n","<br />")) print(msg) sys.stdout.flush() def received(self, msg): self.ui.txtRecv.appendHtml("<span style='font-weight:bold;color:blue'>recv:</span> " + escape_html(msg).rstrip("\n").replace("\n","<br />")) def clear_worker_table(self): self.worker = {} self.ui.cbxId.clear() def add_worker(self, id, name, group, proposition, propCaption, propScore, processedScore, problemScore, blocked, working): self.worker[id] = (name, proposition, propCaption, propScore) self.ui.cbxId.clear() self.ui.cbxId.addItems(sorted(self.worker.keys())) def display_proposition_by_cbxId_index(self, idx): ## DEBUG #sys.stderr.write(">> display_proposition_by_cbxId_index %d\n" % idx) #sys.stderr.flush() if idx > -1: workerId = str(self.ui.cbxId.itemText(idx)) if workerId in self.worker: ## DEBUG #sys.stderr.write(">> %s\n" % workerId) #sys.stderr.flush() (workerName, lastProposition, lastPropCaption, lastPropScore) = self.worker[workerId] self.ui.lblWorker.setText("<html><body><p style='font-size:12pt'><b>" + workerName + "</b></p></body></html>") self.ui.lblScore.setText("<html><body><p style='font-size:12pt'><b>Score: </b>" + str(lastPropScore) + "</p></body></html>") self.paintBox.drawProposition(lastProposition)
from flask import Flask from flask import redirect, url_for, request, render_template from werkzeug.exceptions import NotFound from jsonreader import JsonReader app = Flask(__name__) posts_data = JsonReader() @app.route('/') def index(): params = { 'footer_needed': False, } return render_template('index.html', **params) @app.route('/posts/') def posts(): params = { 'footer_needed': True, 'footer_address_needed': False, 'posts_count': posts_data.getPostCount(), 'posts': posts_data.getPostsList(), } return render_template('posts.html', **params) @app.route('/posts/global_<int:fromID>_<int:postID>/') def posts_postID(fromID, postID): params = {
def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # status bar self.labelProblemSpec = QtGui.QLabel() self.labelProblemTime = QtGui.QLabel() self.labelCurrentRound = QtGui.QLabel() self.labelWorkerInput = QtGui.QLabel() self.ui.statusbar.addWidget(self.labelProblemSpec, 1) self.ui.statusbar.addWidget(self.labelProblemTime, 1) self.ui.statusbar.addWidget(self.labelCurrentRound, 1) self.ui.statusbar.addWidget(self.labelWorkerInput, 1) # set menu shortcuts self.ui.actionLoadGameState.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+O"))) self.ui.actionSaveGameState.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+S"))) self.ui.actionQuit.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+Q"))) self.ui.actionStartRound.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+R"))) self.ui.actionAddScores.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+A"))) self.ui.actionKillAllWorkers.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+K"))) self.DataCollector = JsonReader(self) self.connect(self.DataCollector, QtCore.SIGNAL("received_data"), self.received) self.connect(self.DataCollector, QtCore.SIGNAL("worker_updated"), self.update_worker) self.connect(self.DataCollector, QtCore.SIGNAL("round_started"), self.start_round) self.connect(self.DataCollector, QtCore.SIGNAL("round_ended"), self.end_round) self.connect(self.DataCollector, QtCore.SIGNAL("worker_input_changed"), self.update_worker_input) self.connect(self.DataCollector, QtCore.SIGNAL("problem_chosen"), self.choose_problem) self.connect(self.DataCollector, QtCore.SIGNAL("all_data"), self.update_all) self.connect(self.DataCollector, QtCore.SIGNAL("save_game_state_reply"), self.save_game_state_reply) self.connect(self.DataCollector, QtCore.SIGNAL("load_game_state_reply"), self.load_game_state_reply) self.DataCollector.start() self.problemAnswerTime = 0 self.roundTimerRemaining = 0 self.roundTimer = QtCore.QTimer() QtCore.QObject.connect(self.roundTimer, QtCore.SIGNAL("timeout()"), self.roundTimer_tick) # file menu QtCore.QObject.connect(self.ui.actionLoadGameState, QtCore.SIGNAL("triggered()"), self.btnLoadGameState_clicked) QtCore.QObject.connect(self.ui.actionSaveGameState, QtCore.SIGNAL("triggered()"), self.btnSaveGameState_clicked) QtCore.QObject.connect(self.ui.actionReloadAllData, QtCore.SIGNAL("triggered()"), self.btnReloadAllData_clicked) QtCore.QObject.connect(self.ui.actionQuit, QtCore.SIGNAL("triggered()"), self.btnQuit_clicked) # round menu QtCore.QObject.connect(self.ui.actionStartRound, QtCore.SIGNAL("triggered()"), self.btnStartRound_clicked) QtCore.QObject.connect(self.ui.actionAddScores, QtCore.SIGNAL("triggered()"), self.btnAddScores_clicked) QtCore.QObject.connect(self.ui.actionKillAllWorkers, QtCore.SIGNAL("triggered()"), self.btnKillAllWorkers_clicked) # worker tab self.ui.tableWorker.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.ui.tableWorker.customContextMenuRequested.connect(self.tableWorker_requestContextMenu) # io tab QtCore.QObject.connect(self.ui.btnSend, QtCore.SIGNAL("clicked()"), self.btnSend_clicked) QtCore.QObject.connect(self.ui.edtSend, QtCore.SIGNAL("returnPressed()"), self.btnSend_clicked) # worker table header thh = self.ui.tableWorker.horizontalHeader() thh.setVisible(True) thh.resizeSection(0, 50) # ranking group thh.resizeSection(1, 60) # id thh.resizeSection(2, 170) # name thh.resizeSection(3, 230) # proposition thh.resizeSection(4, 100) # points thh.resizeSection(5, 50) # processed points thh.resizeSection(6, 100) # problem points (accumulated over all rounds on this problem) thh.setSortIndicator(1, QtCore.Qt.AscendingOrder) tvh = self.ui.tableWorker.verticalHeader() tvh.setVisible(True) tvh.setResizeMode(QtGui.QHeaderView.Fixed) self.reset_problem_list([]) self.worker_blocked = {}
class MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # status bar self.labelProblemSpec = QtGui.QLabel() self.labelProblemTime = QtGui.QLabel() self.labelCurrentRound = QtGui.QLabel() self.labelWorkerInput = QtGui.QLabel() self.ui.statusbar.addWidget(self.labelProblemSpec, 1) self.ui.statusbar.addWidget(self.labelProblemTime, 1) self.ui.statusbar.addWidget(self.labelCurrentRound, 1) self.ui.statusbar.addWidget(self.labelWorkerInput, 1) # set menu shortcuts self.ui.actionLoadGameState.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+O"))) self.ui.actionSaveGameState.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+S"))) self.ui.actionQuit.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+Q"))) self.ui.actionStartRound.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+R"))) self.ui.actionAddScores.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+A"))) self.ui.actionKillAllWorkers.setShortcut(QtGui.QKeySequence(self.tr("Ctrl+K"))) self.DataCollector = JsonReader(self) self.connect(self.DataCollector, QtCore.SIGNAL("received_data"), self.received) self.connect(self.DataCollector, QtCore.SIGNAL("worker_updated"), self.update_worker) self.connect(self.DataCollector, QtCore.SIGNAL("round_started"), self.start_round) self.connect(self.DataCollector, QtCore.SIGNAL("round_ended"), self.end_round) self.connect(self.DataCollector, QtCore.SIGNAL("worker_input_changed"), self.update_worker_input) self.connect(self.DataCollector, QtCore.SIGNAL("problem_chosen"), self.choose_problem) self.connect(self.DataCollector, QtCore.SIGNAL("all_data"), self.update_all) self.connect(self.DataCollector, QtCore.SIGNAL("save_game_state_reply"), self.save_game_state_reply) self.connect(self.DataCollector, QtCore.SIGNAL("load_game_state_reply"), self.load_game_state_reply) self.DataCollector.start() self.problemAnswerTime = 0 self.roundTimerRemaining = 0 self.roundTimer = QtCore.QTimer() QtCore.QObject.connect(self.roundTimer, QtCore.SIGNAL("timeout()"), self.roundTimer_tick) # file menu QtCore.QObject.connect(self.ui.actionLoadGameState, QtCore.SIGNAL("triggered()"), self.btnLoadGameState_clicked) QtCore.QObject.connect(self.ui.actionSaveGameState, QtCore.SIGNAL("triggered()"), self.btnSaveGameState_clicked) QtCore.QObject.connect(self.ui.actionReloadAllData, QtCore.SIGNAL("triggered()"), self.btnReloadAllData_clicked) QtCore.QObject.connect(self.ui.actionQuit, QtCore.SIGNAL("triggered()"), self.btnQuit_clicked) # round menu QtCore.QObject.connect(self.ui.actionStartRound, QtCore.SIGNAL("triggered()"), self.btnStartRound_clicked) QtCore.QObject.connect(self.ui.actionAddScores, QtCore.SIGNAL("triggered()"), self.btnAddScores_clicked) QtCore.QObject.connect(self.ui.actionKillAllWorkers, QtCore.SIGNAL("triggered()"), self.btnKillAllWorkers_clicked) # worker tab self.ui.tableWorker.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.ui.tableWorker.customContextMenuRequested.connect(self.tableWorker_requestContextMenu) # io tab QtCore.QObject.connect(self.ui.btnSend, QtCore.SIGNAL("clicked()"), self.btnSend_clicked) QtCore.QObject.connect(self.ui.edtSend, QtCore.SIGNAL("returnPressed()"), self.btnSend_clicked) # worker table header thh = self.ui.tableWorker.horizontalHeader() thh.setVisible(True) thh.resizeSection(0, 50) # ranking group thh.resizeSection(1, 60) # id thh.resizeSection(2, 170) # name thh.resizeSection(3, 230) # proposition thh.resizeSection(4, 100) # points thh.resizeSection(5, 50) # processed points thh.resizeSection(6, 100) # problem points (accumulated over all rounds on this problem) thh.setSortIndicator(1, QtCore.Qt.AscendingOrder) tvh = self.ui.tableWorker.verticalHeader() tvh.setVisible(True) tvh.setResizeMode(QtGui.QHeaderView.Fixed) self.reset_problem_list([]) self.worker_blocked = {} def closeEvent(self, e): self.send(json.dumps({'action': 'quit program'})) self.DataCollector.terminate() # TODO: "This function is dangerous and its use is discouraged" self.DataCollector.wait() e.accept() app.exit() ############################### ## main menu / buttons ## ############################### ## file menu def btnLoadGameState_clicked(self): fileName = str(QtGui.QFileDialog.getOpenFileName()) if fileName != "": self.send(json.dumps({'action': 'load game state', 'file path': fileName})) def btnSaveGameState_clicked(self): fileName = str(QtGui.QFileDialog.getSaveFileName()) if fileName != "": self.send(json.dumps({'action': 'save game state', 'file path': fileName})) def btnReloadAllData_clicked(self): self.send(json.dumps({'action': 'get all data'})) def btnQuit_clicked(self): self.close() ## problems menu def btnChooseProblem_clicked(self, idx, action, oldChecked): action.setChecked(oldChecked) # undo auto check self.send(json.dumps({'action': 'choose problem', 'problem idx': idx})) ## round menu def btnStartRound_clicked(self): self.send(json.dumps({'action': 'start round'})) def btnAddScores_clicked(self): self.send(json.dumps({'action': 'add scores'})) self.ui.actionAddScores.setEnabled(False) def btnKillAllWorkers_clicked(self): self.send(json.dumps({'action': 'kill all workers'})) ## worker tab def tableWorker_requestContextMenu(self, position): workerId = str(self.ui.tableWorker.item(self.ui.tableWorker.currentRow(), 1).text()) # create menu menu = QtGui.QMenu() actApply = menu.addAction("&Apply proposition") actBlock = None actUnblock = None if self.worker_blocked[workerId]: actUnblock = menu.addAction("Un&block worker '" + workerId + "'") else: actBlock = menu.addAction("&Block worker '" + workerId + "'") # execute menu synchronously action = menu.exec_(self.ui.tableWorker.viewport().mapToGlobal(position)) if action != None: if action == actApply: if QtGui.QMessageBox.information(self, "Apply proposition", "Really apply proposition from " + workerId + "?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) == QtGui.QMessageBox.Yes: self.send(json.dumps({'action': 'apply proposition', 'worker id': workerId})) elif action == actBlock: self.send(json.dumps({'action': 'block worker', 'worker id': workerId})) elif action == actUnblock: self.send(json.dumps({'action': 'unblock worker', 'worker id': workerId})) ## io tab def btnSend_clicked(self): msg = self.ui.edtSend.text() self.send(msg) self.ui.edtSend.clear() ####################### ## Round timer ## ####################### def roundTimer_tick(self): self.roundTimerRemaining -= self.roundTimer.interval() if self.roundTimerRemaining <= 0: self.roundTimer.stop() self.roundTimerRemaining = 0 self.labelProblemTime.setText("Answer time remaining\n " + str(self.roundTimerRemaining/1000) + "s") ####################### ## JSON events ## ####################### def update_worker(self, id, proposition, caption, score, processedScore, problemScore, blocked, working): row = self.get_worker_table_row(id) if proposition == None: proposition = "" if row != None: self.update_worker_by_row(row, id, proposition, caption, score, processedScore, problemScore, blocked, working) def start_round(self, round): self.ui.actionStartRound.setEnabled(False) self.ui.menuProblems.setEnabled(False) self.ui.actionAddScores.setEnabled(False) self.labelCurrentRound.setText("Round (running)\n " + str(round)) self.roundTimerRemaining = self.problemAnswerTime self.roundTimer.start(100) def end_round(self, round): self.ui.actionStartRound.setEnabled(True) self.ui.menuProblems.setEnabled(True) self.ui.actionAddScores.setEnabled(True) self.labelCurrentRound.setText("Round\n " + str(round)) self.roundTimerRemaining = 0 self.roundTimer_tick() def update_worker_input(self, workerInput): def format_wi_line(line): return shorten_string(28, line) wiString = "\n".join(list(map(format_wi_line, workerInput))) self.labelWorkerInput.setText("Worker input for next round:\n" + wiString) def choose_problem(self, problemIdx): self.roundTimer.stop() self.reset_problem_list(self.problemList, problemIdx) probDesc, probSpec, answerTime, startState = self.problemList[problemIdx] self.labelProblemSpec.setText("Problem\n " + probDesc) self.labelProblemTime.setText("Answer time\n " + str(answerTime/1000.0) + "s") self.problemAnswerTime = answerTime self.labelCurrentRound.setText("") def update_all(self, running, workerList, problemList, problemIdx, round, workerInput, problemState): self.clear_worker_table() for id, name, group, proposition, caption, score, processedScore, problemScore, blocked, working in workerList: self.add_worker(id, name, group, proposition, caption, score, processedScore, problemScore, blocked, working) self.update_worker_input(workerInput) if running: self.start_round(round) else: self.end_round(round) self.problemList = problemList self.choose_problem(problemIdx) def save_game_state_reply(self, result): if result == "ok": msg = "Game state successfully saved." QtGui.QMessageBox.information(self, "Game state saved", msg, QtGui.QMessageBox.Ok) else: if result == "enoent" : msg = "No such file or directory!" elif result == "enotdir": msg = "Not a directory!" elif result == "enospc" : msg = "No space left on device!" elif result == "eacces" : msg = "Permission denied!" elif result == "eisdir" : msg = "Illegal operation on a directory!" else : msg = "Unknown error: " + result QtGui.QMessageBox.warning(self, "Error saving game state", msg, QtGui.QMessageBox.Ok) def load_game_state_reply(self, result): if result == "ok": msg = "Game state successfully loaded." QtGui.QMessageBox.information(self, "Game state loaded", msg, QtGui.QMessageBox.Ok) else: if result == "eformat": msg = "Invalid file format!" elif result == "enoent" : msg = "No such file or directory!" elif result == "enotdir": msg = "Not a directory!" elif result == "eacces" : msg = "Permission denied!" elif result == "eisdir" : msg = "Illegal operation on a directory!" else : msg = "Unknown error: " + result QtGui.QMessageBox.warning(self, "Error loading game state", msg, QtGui.QMessageBox.Ok) ############################# ## private functions ## ############################# def send(self, msg): self.ui.txtRecv.appendHtml("<span style='font-weight:bold;color:red'>send:</span> " + escape_html(msg).rstrip("\n").replace("\n","<br />")) print(msg) sys.stdout.flush() def received(self, msg): self.ui.txtRecv.appendHtml("<span style='font-weight:bold;color:blue'>recv:</span> " + escape_html(msg).rstrip("\n").replace("\n","<br />")) def get_worker_table_row(self, id): for row in range(0, self.ui.tableWorker.rowCount()): if self.ui.tableWorker.item(row, 1).text() == id: return row return None def clear_worker_table(self): self.worker_blocked = {} self.ui.tableWorker.clearContents() self.ui.tableWorker.setRowCount(0) def add_worker(self, id, name, group, proposition, propCaption, score, processedScore, problemScore, blocked, working): if proposition == None: proposition = "" self.worker_blocked[id] = blocked != "no" row = self.ui.tableWorker.rowCount() self.ui.tableWorker.setRowCount(row + 1) self.ui.tableWorker.setSortingEnabled(False) item = QtGui.QTableWidgetItem() item.setText(group) self.ui.tableWorker.setItem(row, 0, item) item = QtGui.QTableWidgetItem() item.setText(id) self.ui.tableWorker.setItem(row, 1, item) item = QtGui.QTableWidgetItem() item.setText(name) self.ui.tableWorker.setItem(row, 2, item) item = QtGui.QTableWidgetItem() self.ui.tableWorker.setItem(row, 3, item) item = CustomTableWidgetItem() item.setTextAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter) self.ui.tableWorker.setItem(row, 4, item) item = CustomTableWidgetItem() item.setTextAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter) self.ui.tableWorker.setItem(row, 5, item) item = CustomTableWidgetItem() item.setTextAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter) self.ui.tableWorker.setItem(row, 6, item) self.update_worker_by_row(row, id, proposition, propCaption, score, processedScore, problemScore, blocked, working) self.ui.tableWorker.setSortingEnabled(True) def update_worker_by_row(self, row, id, proposition, propCaption, score, processedScore, problemScore, blocked, working): isBlocked = blocked != "no" blockedIdx = blocked["idx"] if "idx" in blocked else 0 self.worker_blocked[id] = isBlocked self.ui.tableWorker.setSortingEnabled(False) brush = QtGui.QBrush(QtGui.QColor(190, 190, 190)) if self.worker_blocked[id]: brush.setStyle(QtCore.Qt.SolidPattern) else: brush.setStyle(QtCore.Qt.NoBrush) self.ui.tableWorker.item(row, 0).setBackground(brush) self.ui.tableWorker.item(row, 1).setBackground(brush) self.ui.tableWorker.item(row, 2).setBackground(brush) item = self.ui.tableWorker.item(row, 3) item.setText(propCaption) item.setBackground(brush) item = self.ui.tableWorker.item(row, 4) item.setText(str(score)) item.setCustomSortData(isBlocked, {False: int(score), True: blockedIdx}[isBlocked]) item.setBackground(brush) item = self.ui.tableWorker.item(row, 5) item.setText(str(processedScore)) item.setCustomSortData(isBlocked, {False: int(processedScore), True: blockedIdx}[isBlocked]) item.setBackground(brush) item = self.ui.tableWorker.item(row, 6) item.setText(str(problemScore)) item.setCustomSortData(isBlocked, {False: int(problemScore), True: blockedIdx}[isBlocked]) item.setBackground(brush) if self.ui.tableWorker.cellWidget(row, 2) == None: if working: self.ui.tableWorker.setCellWidget(row, 2, WorkingWidget(self)) else: if not working: self.ui.tableWorker.removeCellWidget(row, 2) self.ui.tableWorker.setSortingEnabled(True) def reset_problem_list(self, lst, checkedIdx=None): self.problemList = lst self.ui.menuProblems.clear() if lst == []: action = QtGui.QAction(self) action.setText("--- no problems ---") action.setEnabled(False) self.ui.menuProblems.addAction(action) else: for idx, (description, spec, answerTime, state) in enumerate(lst): action = QtGui.QAction(self) action.setText(description + "\t" + str(answerTime/1000.0) + "s") action.setCheckable(True) if checkedIdx == idx: action.setChecked(True) QtCore.QObject.connect(action, QtCore.SIGNAL("triggered()"), lambda i=idx, a=action, chk=(checkedIdx==idx): self.btnChooseProblem_clicked(i, a, chk)) self.ui.menuProblems.addAction(action)